標籤:
題目描述
零崎有很多朋友,其中有一個叫做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 12 14 33 11 32 2
輸出範例
jpx4
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 else24 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 }
0-1背包修改版