(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 ...