动态规划的题总是 看完别人的代码自己理解着打,今天自己终于自己打一回,遇到了一点问题,不过解决后发现现在理解更透彻了。
Problem Description
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
Input
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
Output
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
Sample Input
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0
Sample Output
-45
32
开始时我用的是先从小到大循环temp,内部从小到大循环cost,发现不仅会重复放置还思路解释不清,后来改为先循环cost再从小到大循环temp,发现会重复放置,就是每次放置是本应改是再上一个放置基础上各个独立的,可这样就会造成再放物体5时,用到了dp[i-cost[5]]但此时的dp[i-cost[5]]由于是从小到大循环,在经过dp[i-cost[5]]时已经被dp[i-cost[5]]改变了(此时的i为dp[i-cost[5]]),哎~ 怎么解释也解释不清啊,才明白写背包九讲的大牛是有多厉害,曾经喜欢VN那个后期adc的“木已成舟”,事已至此又能怎样,反正过去的也改变不了,只好努力。
/*啊啊啊啊啊啊啊啊啊,打完这些才明白这道题是有多简单,我是有多脑残啊啊啊啊啊啊啊*/(说点没用的啊,学校训练赛已经开始了,而我还在写这道题,无语了)
1 /*01背包HDU2546*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 int cost[1010]; 7 int dp[1010]; 8 int main() 9 { 10 int n,money; 11 while(cin>>n&&n) 12 { 13 14 for(int i=0; i<n; i++) 15 cin>>cost[i]; 16 sort(cost,cost+n); 17 cin>>money; 18 if(money<5){ 19 cout<<money<<endl; 20 continue; 21 } 22 int temp=money-5; 23 memset(dp,0,sizeof(dp)); 24 for(int i=0; i<n-1; i++) 25 for(int j=temp; j>=1; j--) 26 if(cost[i]<=j) 27 { 28 dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]); 29 // cout<<dp[j]<<endl; 30 } 31 cout<<money-dp[temp]-cost[n-1]<<endl; 32 } 33 }