零崎的朋友很多Ⅱ(101)[01背包,要求填满]
Posted loganlzj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了零崎的朋友很多Ⅱ(101)[01背包,要求填满]相关的知识,希望对你有一定的参考价值。
零崎的朋友很多Ⅱ
时间限制: 2000 ms 内存限制: 65536 kb
总通过人数: 437 总提交人数: 460
题目描述
零崎有很多朋友,其中有一个叫做lfj的接盘侠。
lfj是一个手残,他和零崎一起玩网游的时候不好好打本,天天看拍卖行,没过多久,就成为了一个出色的商人。不过再出色的投机商也有失手成为接盘侠的一天。所谓真正的接盘侠从来不给自己留活路。当lfj接盘成功之时,即分文不剩之日。
作为lfj的友人,零崎实在看不下去,于是他决定帮lfj一把。当然了,零崎肯定不会自己动手,活还得你们来干。
lfj可以提供给你们拍卖行所有能买到物品的价格和利润,还有他的本金。既然是接盘侠,就必须分文不剩。虽然零崎想让你们给出一次接盘中利润最大的购买方案,但是lfj觉得只要知道最大利润就可以了。
输入
每组数据第一行为两个整数P和N,表示本金和拍卖行物品个数。(注意:与B题不同每类物品只有一件
接下来N行,每行两个数据pi,ci代表第i类物品的利润和购买价格。
1<=P<=20000,1<=N<=300,1<=c,p<=200
输出
对于每组数据,输出一行,为能获得的最大利润
如果不能成功接盘,则输出jpx
输入样例
3 1
2 1
4 3
3 1
1 3
2 2
输出样例
jpx
4
Hint
使用if直接比较不要调用max()以防超时
题解
01背包且要求装满,与最基本的01背包问题差别在于dp数组初始化时,只将dp[0]初始化为0,其他dp[i]初始化为负无穷,这样保证了在这些状态基础上生成的非法状态(背包未填满)的值始终为负,在max时也不会被选择。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long LL; 7 const int maxv=20007; //背包空间上限 8 const int maxk=307;//物品数上限 9 const int negainf=-9999999; 10 int v[maxk],w[maxk];//w为重量,v为价值 11 LL dp[maxv]; 12 int c,n;//背包空间和物品数 13 14 void init_full(){ //题目要求背包必须装满时的初始化方法,最原始状态只有dp[0]为0,其他为负无穷,使得只有在dp[0]基础上生成的状态(即背包被装满的状态)才为正值 15 memset(dp,0,sizeof(dp)); 16 dp[0]=0; 17 for(int i=1;i<=c;++i){ 18 dp[i]=negainf; 19 } 20 } 21 void start_dp(){ 22 for(int i=0;i<n;++i){ 23 for(int j=c;j>=w[i];--j){ 24 if(dp[j-w[i]]+v[i]>dp[j]){ 25 dp[j]=dp[j-w[i]]+v[i]; 26 } 27 } 28 } 29 } 30 int main(){ 31 while(~scanf("%d%d",&c,&n)){ 32 init_full(); 33 for(int i=0;i<n;++i){ //物品从0至k 34 scanf("%d%d",&v[i],&w[i]); 35 } 36 start_dp(); 37 if(dp[c]>=0){ 38 printf("%lld ",dp[c]); 39 } 40 else{ 41 printf("jpx "); 42 } 43 } 44 }
以上是关于零崎的朋友很多Ⅱ(101)[01背包,要求填满]的主要内容,如果未能解决你的问题,请参考以下文章