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
");
23         else
24             printf("%d
",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 }
原文地址:https://www.cnblogs.com/zpfbuaa/p/4966349.html