01 Problema de mochila mediana

Algoritmo veinte días

día 18

01 Problema de mochila
Descripción del problema:

Dados n artículos, el peso del artículo es w [i] y el valor del artículo es c [i]. Ahora seleccione los artículos para poner en la mochila, suponiendo que el peso máximo que puede soportar la mochila es V, ¿cómo elegir los artículos en la mochila para que el valor total de los artículos en la mochila sea el mayor?

Ejemplo:

w[]={2,2,6,5,4};
v[]={6,3,5,4,6};
n=5,c=10;
máx: 15

Este es un ejemplo típico de programación dinámica. La esencia de la programación dinámica es la recursividad, como la secuencia de Fibonacci.
Si usamos la recursividad para calcular f(6), entonces necesitamos calcular f(4) y f(5) ; ambos f (4) y f (5) recurrirán a f (1) o f (2) durante el proceso recursivo , lo que significa que f (4) y f (5) tienen cálculos repetidos, lo que hace que la complejidad del tiempo cambie grande. La programación dinámica es en realidad registrar los resultados del cálculo. Cuando se usa, puede buscar directamente en la tabla. También existe una diferencia entre la programación dinámica y divide y vencerás, porque dividir y conquistar requiere que los subproblemas sean independientes. unos de otros Obviamente, los subproblemas de las preguntas de programación dinámica son dependientes.

Mirando nuevamente esta pregunta, primero determine si tiene una estructura de subproblema óptima. Esto es fácil de probar. Podemos simplemente pensar que si la capacidad es j y el número de elementos que se pueden tomar es i, lo que se toma no es el Valor máximo, incluso si lo siguiente Algunos toman el más grande, pero en general no es el más grande.

Supongamos que map[i][j] es el valor máximo cuando la capacidad es j y los elementos que se pueden cargar son los primeros i, entonces podemos construir la tabla nuevamente.

#include <bits/stdc++.h>
#include <vector>
using namespace std;

int main()
{
    
    
	int w[]={
    
    0,2,2,6,5,4};
	int v[]={
    
    0,6,3,5,4,6};//对应平时习惯,把数组变为1为开始。
	int n=5,c=10;
	int map[6][11]={
    
    0};//对应平时习惯
	for(int i=1;i<=5;i++)//当容量为2时,最大价值,也是递归基
		map[i][2]=6;
	for(int i=1;i<=5;i++)	
		for(int j=3;j<=10;j++)	
		{
    
    
			if(j>w[i])//容量大于它才能拿。
				map[i][j]=max(map[i-1][j],map[i-1][j-w[i]]+v[i]);
			else
				map[i][j]=map[i-1][j];
			}
	cout<<map[5][10];
}

Retroceder

#include<bits/stdc++.h>
using namespace std;

int v[]={
    
    12,11,9,8};
int w[]={
    
    8,6,4,3};
int b=13;
//例子
int sum=0;
int answer=0;

void f(int i,int bei)
{
    
    

	if(i==5)
	{
    
    
		answer=answer>sum?answer:sum;
		return;
	}
	
	if(bei>=w[i])//拿
	{
    
    
		sum+=v[i];
		f(i+1,bei-w[i]);
		sum-=v[i];//还原现场
	}
	f(i+1,bei);//不拿
}

int main()
{
    
    
	f(0,13);
	cout<<answer;
}

Supongo que te gusta

Origin blog.csdn.net/BeiWoFW/article/details/124462446
Recomendado
Clasificación