Publicado originalmente en:
El estanque estaba lleno y la lluvia se detuvo. Loach estaba por todas partes en el lodo en el borde del campo.
Sin embargo, en lugar de pescar lochas hoy, capturaremos cangrejos y partiremos un poco más tarde. Tome una bolsa, por supuesto, cuanto más atrape, mejor, así que pensé en una pregunta clásica similar:
Los ladrones pueden robar muchos tesoros por la noche, pero el peso de la mochila es limitado ¿Cuál es el beneficio máximo?
Este es un problema típico de la mochila 0/1. ¿Por qué se llama el problema de la mochila 0/1? Porque para un tesoro, el ladrón elige robarlo o elige no robarlo. El ladrón está en un dilema Analizamos y concretizamos la dificultad del ladrón.
Supongamos que el ladrón entra en la tierra del tesoro y encuentra 4 tesoros. El valor V es 2 yuanes, 3 yuanes, 4 yuanes y 5 yuanes, y el peso correspondiente W es 1 malicioso, 2 malicioso, 3 malicioso y 4 malicioso. El ladrón La mochila es la más grande El peso es de 7 kg, entonces, ¿cuál es el beneficio máximo del ladrón?
yo | 1 | 2 | 3 | 4 |
V | 2 yuanes | 3 yuanes | 4 yuanes | 5 yuanes |
W | 1 malicioso | 2 gatos | 3 gatos | 4 gatos |
Obviamente, la programación dinámica se puede utilizar para pensar y encontrar la relación de recurrencia. Definamos el estado: bajo el límite de carga j, sea f [i] [j] el beneficio máximo que se puede lograr con el primer elemento i. Entonces, F [4] [7] es el objetivo del ladrón. El problema ahora es: pregunte por la relación de recurrencia de f [i] [j].
Cuando examinamos el tesoro i-ésimo, solo hay dos situaciones: el ladrón lo elige o no lo elige. Luego, en estos dos casos, se obtiene el valor mayor y se forma una relación de recurrencia. Mirando el programa directamente, la relación de recurrencia se refleja en él:
#include<iostream>
using namespace std;
#define N 4 // 总共N件宝贝
#define V 7 // V是背包的承重极限值
int main()
{
int value[N + 1] = {0, 2, 3, 4, 5}; // 宝贝的价值
int weight[N + 1] = {0, 1, 2, 3, 4}; // 宝贝的重量
int f[N + 1][V + 1] = {0}; // f[i][j]表示在背包承重为j的情况下,前i件宝贝的最大价值
int i = 1;
int j = 1;
for(i = 1; i <= N; i++)
{
for(j = 1; j <= V; j++)
{
// 递推关系式
if(j < weight[i])
{
f[i][j] = f[i - 1][j];
}
else
{
int x = f[i - 1][j]; // case1: 不选择第i件宝贝
int y = f[i - 1][j - weight[i]] + value[i]; // case2: 选择第i件宝贝
f[i][j] = x < y ? y : x;
}
}
}
cout << f[N][V] << endl; // 10
return 0;
}
El resultado del procedimiento es de 10 yuanes, que es la mayor ganancia del ladrón.
En el artículo anterior hablamos de programación dinámica: la esencia de la programación dinámica . El dominio de la programación dinámica puede obtener el máximo beneficio y se pueden capturar más cangrejos.
Ve, atrapa el cangrejo.