0-1背包修改版
题目描述
零崎有很多朋友,其中有一个叫做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()以防超时
题目来源:http://biancheng.love/contest/17/problem/C/index
解题分析:改题和0-1背包问题类似,不过要求实现将背包的整个容量V,也就是题目中的本金P,全部用尽,同时要求得到利润最大。需要对装入的每件商品进行判断,首先是能否满足耗尽本金,另外判断是否比上次的利润大。
先给出关键的代码段配合思考:
1 for(int i=0;i<n;i++) 2 { 3 scanf("%d%d",&pi,&ci); 4 for(int j=p; j >= ci; j--) 5 if(V[j-ci]!=-1&&V[j]<V[j-ci]+pi) 6 V[j]=V[j-ci]+pi; 7 }
明白上述讲解之后,下面的输出以及输入只是按照题目要求进行。
代码实现:
1 #include <bits/stdc++.h> 2 #define max_size 20010 3 int V[max_size]; 4 5 using namespace std; 6 7 int main() 8 { 9 int p,n,pi,ci; 10 while(~scanf("%d%d",&p,&n)) 11 { 12 memset(V,-1,sizeof(V)); 13 V[0]=0; 14 for(int i=0;i<n;i++) 15 { 16 scanf("%d%d",&pi,&ci); 17 for(int j=p; j >= ci; j--) 18 if(V[j-ci]!=-1&&V[j]<V[j-ci]+pi) 19 V[j]=V[j-ci]+pi; 20 } 21 if(V[p]==-1) 22 printf("jpx\n"); 23 else 24 printf("%d\n",V[p]); 25 } 26 }
另附0-1背包的实现代码:
1 void ZoreOnePack(int cost , int weight) 2 { 3 for (int i = W ; i >= weight ; -- i) 4 f[i] = max(f[i],f[i-weight]+cost) ; 5 }
作者: 伊甸一点
出处: http://www.cnblogs.com/zpfbuaa/
本文版权归作者伊甸一点所有,欢迎转载和商用(须保留此段声明),且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文链接 如有问题, 可邮件(zpflyfe@163.com)咨询.