[Preliminar (3) del Concurso de Programación Online Super Code Force] Prefijo de teñido de la casa y + dp multidimensional

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+1t )

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;
	}
};

Supongo que te gusta

Origin blog.csdn.net/weixin_44235989/article/details/108456585
Recomendado
Clasificación