Agenda de aprendizaje de planificación dinámica (2)

(Esta vez son dos ejemplos simples de diferentes tipos)

0 0 1 2 3 4 4 5 5 6 6 7 7
1 1 1 1 1 1 1 1
2 1 2 3 4 4 5 5 6 6 7 7
3 1 3 6 6 10 15 21 28

Ejemplo 2 , hay m filas yn columnas de cuadrícula, desde la esquina superior izquierda hasta la esquina inferior derecha, averigua cuántas formas (la cantidad de formas)

Análisis:

1. Determine el estado:

Punto final: las coordenadas de la esquina inferior derecha son (m-1, n-1), las coordenadas del paso anterior deben ser (m-2, n-1) o (m-1, n-2);

Subproblema: Usando el principio de la suma, hay x formas de alcanzar (m-2, n-1), y hay y formas de alcanzar (m-1, n-2), entonces hay

X + y formas de llegar al final. Sea f [i] [j] el número de modos.

2. Determine la ecuación de transferencia:

f [i] [j] = f [i - 1] [j] + f [i] [j - 1]

3. Determine las condiciones iniciales y las condiciones de contorno:

Condición inicial: f [0] [0] = 1;

Condiciones de contorno: i == 0 || j == 0, f [i] [j] = 1;

4. Determine el orden de cálculo:

Calcule fila por fila porque se conocen los valores iniciales de las filas y columnas de límites

Código:

#include <iostream>
#include <cstring>
using namespace std;
int mp[100][100];
void Init(int m, int n){
	int i, j;
	for(i = 0; i < m; i++)
	{
	 	mp[i][0] = 1;
	}
	for(i = 0; i < n; i++)
	{
	 	mp[0][i] = 1;
	}
}
void Fill(int m, int n){
	int i, j;
	for(i = 1; i < m; i++)
	{
	 	for(j = 1; j < n; j++)
		 mp[i][j] = mp[i-1][j] + mp[i][j-1];
	}

}
int main(int argc, char** argv) {
	memset(mp, 0, sizeof(m));
    int m, n;
	cin>>m>>n;
	Init(m, n); 
	Fill(m, n);
	cout<<mp[m-1][n-1]<<endl;
	return 0;
}

Ejemplo 3 Hay n piedras, una rana salta de la posición 0 a n-1, la rana se para en la piedra i, y puede saltar ai a la derecha como máximo, preguntando si la rana puede saltar a la piedra n-1 (problema existente)

1. Determine el estado:

Punto final: la posición n-1, la posición del paso anterior n-1, debe cumplir: 1, i <n-1; 2, la rana puede saltar de 0 a i; 3, n-1-i <= ai;

Subpregunta: deje que f [j] indique si la rana puede saltar a la piedra j

2. Determine la ecuación de transferencia:

f [j] = OR (0 <= i <j) (f [i] AND i + a [i]> = j) (0 <= i <j: enumere la última piedra i, f [i]: ¿Puede la rana saltar a i, i + a [i]> = j: límite de distancia del punto final)

3. Determine las condiciones iniciales y las condiciones de contorno:

Condición inicial: f [0] = Verdadero, sin límite

4. Determine el orden de cálculo:

Desde f [j] = OR (0 <= i <j) (f [i] AND i + a [i]> = j), el orden es de pequeño a grande

Código:

#include <iostream>
#include <cstring>
using namespace std;
int a[100];
int f[100];
void Init(){
	memset(a, 0 ,sizeof(a));
	memset(f, 0 ,sizeof(f));
	f[0] = 1;
	
}
void F(int n){
	int i, j, flag;
	for (i = 1; i < n;i++)
	{
		flag = 0;
		for(j = 0; j <= i - 1;j++)
		{
			if(f[j] == 0 || j + a[j] < i)
			{
				continue;	
			}
			else
			{
				flag = 1;
				break;
			}	
		}
		if(flag)
		{
			f[i] = 1;
		}
		else
		{
			f[i] = 0;
		}	
	}
}
int main(int argc, char** argv) {
	Init();
	int n;
	cin>>n;
	int i;
	for(i = 0; i < n; i++)
	{
		cin>>a[i];
	}
	F(n);
	cout<<f[n - 1]<<endl;
	return 0;
}

** Resumen: ** Forma general de la ecuación de transferencia: problema de valor máximo: min o max {...}; problema de conteo: f [...] + f [...]; problema de existencia:
O ... Y ...

Publicado 3 artículos originales · elogiado 3 · visitas 33

Supongo que te gusta

Origin blog.csdn.net/weixin_43869733/article/details/105603137
Recomendado
Clasificación