Enlace de tema: teñido de la casa
Título
Permíteme simplificar el significado de la pregunta y darte una matriz n * k. Seleccionamos un número de cada fila para que la suma de los n números seleccionados en n filas sea la más pequeña. Hay una restricción en la selección. Si los números seleccionados en filas consecutivas están en la misma columna, Tome como máximo t filas, y las filas adyacentes restantes no pueden tomar el número en la misma columna Pregunte el valor mínimo.
responder
Según el significado de la pregunta, 1≤n, k≤100, esta pregunta no parece tener ninguna estrategia codiciosa, parece que solo aparece grácil violento dp.
Evidentemente, dp necesita tres dimensiones para responder al funcionamiento de esta pregunta.
Definición: dp [i] [j] [k]: La primera fila i, la última fila selecciona la columna j-ésima y el valor mínimo cuando se cumple la condición k.
(Hay dos casos para k, 0 significa que no hay una fila continua para seleccionar la misma columna, 1 significa que se ha seleccionado la misma columna en una fila continua).
初始化 :dp [0] [j] [0] = dp [0] [j] [1] = costos [0] [j] (j ∈ [0, m)) {dp [0] [j] [0 ] = dp [0] [j] [1] = costos [0] [j] (j \ in [0, m))}d p [ 0 ] [ j ] [ 0 ]=d p [ 0 ] [ j ] [ 1 ]=c o s t s [ 0 ] [ j ] ( j∈[ 0 ,m ) )
(comienza desde la fila 0 y la columna 0)
状态 转移 :
dp [i] [j] [0] = min (dp [i - 1] [k] [0]) + costos [i] [j] (k ∈ [0, m) y (k ≠ j ) {dp [i] [j] [0] = min (dp [i-1] [k] [0]) + costos [i] [j] (k \ in [0, m) y (k ≠ j )}d p [ i ] [ j ] [ 0 ]=m i n ( d p [ i-1 ] [ k ] [ 0 ] )+c o s t s [ i ] [ j ] ( k∈[ 0 ,m ) y n d ( k=j )
dp [i] [j] [1] = min (dp [i - 1] [k] [1]) + costos [i] [j] (k ∈ [0, m) y (k ≠ j) {dp [i] [j] [1] = min (dp [i-1] [k] [1]) + costos [i] [j] (k \ in [0, m) y (k ≠ j) }d p [ i ] [ j ] [ 1 ]=m i n ( d p [ i-1 ] [ k ] [ 1 ] )+c o s t s [ i ] [ j ] ( k∈[ 0 ,m ) y n d ( k=j )
Tenga en cuenta que cuando k pasa de 0 a 1, obviamente es necesario enumerar la situación en la que comienza la i-ésima fila y la j-ésima columna se selecciona para las anteriores 1 a t filas.
Así que necesitamos contar una suma de prefijo, suma [i] [j]: la suma del valor de la primera fila i en la columna j.
dp [i] [j] [1] = min (dp [l] [j] [0] + suma [i] [j] - suma [l] [j]) (l ∈ [0, i - 1] y (i - l + 1 ≤ t)) {dp [i] [j] [1] = min (dp [l] [j] [0] + suma [i] [j] -sum [l] [j ]) (l \ en [0, i-1] y (i-l + 1≤t))}d p [ i ] [ j ] [ 1 ]=m i n ( d p [ l ] [ j ] [ 0 ]+s u m [ i ] [ j ]-s u m [ i ] [ j ] ) ( l∈[ 0 ,yo-1 ] y n d ( yo-l+1≤t ) )
La respuesta final es: min (dp [n - 1] [j] [0], dp [n - 1] [j] [1]), j ∈ [0, m) {min (dp [n-1] [ j] [0], dp [n-1] [j] [1]), j \ en [0, m)}m i n ( d p [ n-1 ] [ j ] [ 0 ] ,d p [ n-1 ] [ j ] [ 1 ] ) ,j∈[ 0 ,m )
La dificultad de esta pregunta es llegar a la definición de dp y la ecuación de transición de estado, y más práctica + pensamiento puede ganar en este tipo de dp multidimensional.
Código
int inf=0x3f3f3f;
class Solution {
public:
/**
* @param costs: costs of paint ith house into color j
* @param t: maximum length of street
* @return: minimum costs of painting all houses
*/
int dp[105][105][2];
int sum[105][105];
int paintHouseIII(vector<vector<int> > &costs, int t) {
// Write your code here.
memset(dp, inf, sizeof(dp));
int n=costs.size(),m=costs[0].size();
for(int j=0;j<m;j++) dp[0][j][0]=dp[0][j][1]=costs[0][j];
for(int j=0;j<m;j++)
for(int i=0;i<n;i++)
{
if(i==0) sum[i][j]=costs[i][j];
else sum[i][j]=sum[i-1][j]+costs[i][j];
}
for(int i=1;i<n;i++)
for(int j=0;j<m;j++)
{
for(int k=0;k<m;k++)
{
if(j!=k)
{
dp[i][j][0]=min(dp[i-1][k][0]+costs[i][j], dp[i][j][0]);
dp[i][j][1]=min(dp[i-1][k][1]+costs[i][j], dp[i][j][1]);
}
}
for(int l=i-1;l>=0;l--)
{
if(i-l+1>t) break;
dp[i][j][1]=min(dp[i][j][1],dp[l][j][0]+sum[i][j]-sum[l][j]);
}
}
int ans=inf;
for(int j=0;j<m;j++)
{
ans=min(ans,dp[n-1][j][0]);
ans=min(ans,dp[n-1][j][1]);
}
return ans;
}
};