(Copa Puente Azul 13° Concurso Provincial) G: Pintura de Bloques de Construcción (Programación Dinámica)

Lea en una n, pregunte cuántas formas diferentes hay, y la respuesta es módulo 1e9+7.

Análisis: esta pregunta es una programación dinámica. Sea f[i][0] el número de soluciones en la primera columna i actualmente completada, f[i][1] represente la finalización actual de la primera i-1 columna y la columna i-ésima Después de terminar el número de soluciones de la anterior, f[i][2] indica que la primera columna i-1 está actualmente completa, y la columna i-ésima actual ha completado el número de soluciones de la el siguiente Entonces la respuesta es f[n][0]

La derivación de la ecuación de transferencia dinámica es la siguiente:

Primero mire de qué estados puede pasar f[i][0]:

Si actualmente queremos poner un bloque de construcción de este tipo , entonces obviamente es recursivo por f[i-1][0] ¿Qué pasa si ponemos un bloque de construcción de este tipo? , que es recursiva por f[i-1][2], es decir, la i-1ª columna ya ha deletreado el siguiente cuadrado. De igual forma, f[i-1][1] puede ser recursiva, es decir, pon tales bloques en la i-ésima columna: , crees que esto es todo el caso, de hecho, este no es todo el caso, está el último caso, que es armar un bloque como este en la parte superior e inferior , que está determinado por f [i-2][0] se obtiene recursivamente, y este es el número de todos los casos.

Es decir , la ecuación de transición recursiva de f[i][0] es f[i][0]=(f[i-1][1]+f[i-1][2]+f[i -1 ][0]+f[i-2][0])% mod

Echemos un vistazo a la ecuación de recurrencia de f[i][1]. Esto es más fácil de considerar. Uno es poner un bloque de construcción de este tipo:

Esta situación se obtiene recursivamente sobre la base de f[i-2][0]. Otra situación es poner tales bloques: , esta situación se obtiene a partir de f[i-1][2], y f[i][1] se obtiene recursivamente a partir de estas dos situaciones.

Es decir , la ecuación de transferencia de f[i][1] es f[i][1]=(f[i-2][0]+f[i-1][2])%mod

 De la misma manera, la ecuación de transferencia de f[i][2] es f[i][2]=(f[i-2][0]+f[i-1][1])%mod

Cabe señalar que la inicialización debe establecerse en f[0][0]=1, y la ecuación recursiva implica f[i-2][], por lo que se deben realizar algunas ecuaciones recursivas en el caso de i>=2 , para evitar fuera de los límites

Después de analizar esto, se analiza básicamente el tema de este tema, y ​​el código se adjunta a continuación.

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
using namespace std;
const int mod=1e9+7;
const int N=1e7+10;
long long f[N][3];
int main()
{
	int n;
	scanf("%d",&n);
	f[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		f[i][0]=(f[i-1][0]+f[i-1][1]+f[i-1][2])%mod;
		if(i>=2) 
		{
			f[i][0]=(f[i][0]+f[i-2][0])%mod;
			f[i][1]=(f[i-2][0]+f[i-1][2])%mod;
			f[i][2]=(f[i-2][0]+f[i-1][1])%mod;
		}
	}
	printf("%lld",f[n][0]%mod);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/AC__dream/article/details/124066067
Recomendado
Clasificación