Programación dinámica: problema de mochila 0-1 (C ++)

Programación dinámica: problema de mochila 0-1

Los pasos generales de la programación dinámica:

  1. Análisis de la estructura del problema
  2. Establecimiento de relaciones recursivas
  3. Cálculo ascendente
  4. Seguimiento de la mejor solución

Ejemplo 0-1 problema de mochila

(Fuente del tema: https://www.acwing.com/problem/content/description/2/)

Descripción del título
Hay N artículos y una mochila con una capacidad de V. Cada artículo solo se puede usar una vez.

El volumen de los artículos es i V i , es el valor de W i .

Averigüe qué artículos cargar en la mochila para que el volumen total de estos artículos no exceda la capacidad de la mochila y el valor total sea el mayor.
Salida del valor máximo.

Formato de entrada
Dos números enteros N y V en la primera línea, separados por espacios, indican respectivamente el número de artículos y el volumen de la mochila.

Luego hay N filas, cada fila dos números enteros V i , W i , separados por espacios, respectivamente, y el volumen del i-ésimo valor de los elementos.

Formato de
salida Muestra un número entero, que representa el valor máximo.

Rango de datos
0 <N, V≤1000
0 <vi, wi≤1000

Ejemplo de entrada
4 5
1 2
2 4
3 4
4 5

Salida de muestra
8

Análisis de problemas
En el caso de un cierto tamaño de la mochila, encuentre el valor más alto del valor total, cada artículo tiene solo dos casos de selección y ninguna selección, y compare el valor total de los dos casos.

f [i] [j] significa mirar solo los primeros i elementos. Si el volumen total es j, ¿cuál es el valor total máximo?
resultado = max {f [n] [0 ~ V]}

f [i] [j]:
1. No elija el i-ésimo elemento, f [i] [j] = f [i-1] [j];
2. Elija el i-ésimo elemento, f [i] [j] = f [i-1] [jv [i];

Elija el más grande y más en dos casos: f [i] [j] = max {1,2}

Inicialización: f [0] [0] = 0;

Inserte la descripción de la imagen aquí

Codigo 1

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;
int n,m;	//n表示物体个数,m表示背包容量 
int f[N][N]; 
int v[N], w[N]	//v[N], w[N] 分别表示每个物品的体积和价值 

int main(){
    
    
	cin >> n >> m;
	for(int i=0; i<n; i++){
    
    
		cin >> v[i] >> w[i];
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++){
    
    
			f[i][j] = f[i-1][j];
			if(j >= v[i])
				f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);
		} 
		
	int res = 0;
	for(int i=0; i<=m; i++)
		res = max(res,f[n][i]);
		
	cout << res << endl;
	return 0;
} 

En la matriz bidimensional f[N][N]basada en la optimización de la matriz bidimensional f[N][N]optimizada para f[N]representar dicho volumen máximo de la mochila antes del i-ésimo valor de j y el número del artículo, una vez por cada bucle exterior, f [m] a actualizar;
Inserte la descripción de la imagen aquí

Codigo 2

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;
int n,m;	//n表示物体个数,m表示背包容量 
int f[N]; 	//表示背包体积为j时前i个物品的最大价值为多少 
int v[N], w[N]	//v[N], w[N] 分别表示每个物品的体积和价值 

int main(){
    
    
	cin >> n >> m;
	for(int i=0; i<n; i++){
    
    
		cin >> v[i] >> w[i];
	}
	for(int i=1; i<=n; i++)
		for(int j=m; j>=v[i]; j--){
    
    
			f[j] = max(f[j], f[j-v[i]] + w[i]);		//f[j]滚动记录最优解 
		} 
		
	cout << f[m] << endl;	
	return 0;
} 

Supongo que te gusta

Origin blog.csdn.net/qq_44524918/article/details/108992114
Recomendado
Clasificación