背包问题——01背包

01背包问题情境:
有n件物品,每件物品的重量为w[i],价值为c[i],现有一个容量为V的背包,问如何选取物品放入背包,使得背包内物品的总价值量最大,其中每种物品都只有一件

核心代码:(要注意这里是逆序枚举的)

for(int i = 1;i <= n;i++){
		for(int v = V;v >= w[i];v--){
			//状态转移方程 
			dp[v] = max(dp[v],dp[v-w[i]] + c[i]);
		}
	}
	

完整代码:

#include <stdio.h>
#include <algorithm>
using namespace std;

const int maxn = 100;  //物品最大件数 
const int maxv = 1000;  //V的上限 
int w[maxn],c[maxn],dp[maxv];  //w为物品重量,c为价值量容量 ,dp就是临时记录的一维数组 
int main(){
	int n,V;
	scanf("%d%d",&n,&V);
	for(int i = 1;i <= n;i++){
		scanf("%d",&w[i]);
	}
	for(int i = 1;i <= n;i++){
		scanf("%d",&c[i]);
	}
	//边界 
	for(int v = 0;v <= V;v++){
		dp[v] = 0;
	}
	
	//以下开始为背包问题模板 
	for(int i = 1;i <= n;i++){
		for(int v = V;v >= w[i];v--){
			//状态转移方程 
			dp[v] = max(dp[v],dp[v-w[i]] + c[i]);
		}
	}
	
	//寻找dp[0...V]中最大的即为答案 
	int max = 0;
	for(int v = 0;v <= V;v++){
		if(dp[v]>max){
			max = dp[v];
		}
	}
	printf("%d\n",max);
	return 0;
}

/*
5 8
3 5 1 2 2
4 5 2 1 3
*/

附上样例:
问题 1100: 采药
https://www.dotcpp.com/oj/problem1100.html?sid=1898870&lang=1#editor
AC代码:

#include <stdio.h>
#include <algorithm>
using namespace std;

int a[10005];
int w[10005];
int f[1000005];

int main()
{
    int t,m;
    scanf("%d %d",&t,&m);
    for(int b = 1; b <= m; b ++){
    	scanf("%d %d",&a[b],&w[b]);
	}
        
    for(int b = 1; b <= m; b ++){
    	for(int c = t; c >= a[b]; c--){
    		f[c]=max(f[c],f[c-a[b]]+w[b]);
		}    
	}   
    f[0] = 0;
    for(int b = 1; b<=t; b ++){
    	f[0]=max(f[0],f[b]);
	}   
    printf("%d",f[0]);
    return 0;

}

/*

70 3
71 100
69 1
1 2

*/
发布了212 篇原创文章 · 获赞 6 · 访问量 6412

猜你喜欢

转载自blog.csdn.net/weixin_42377217/article/details/104255534