连接:http://acm.hdu.edu.cn/showproblem.php?pid=2546php
#题目描述:c++
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买以前判断余额。若是购买一个商品以前,卡上的剩余金额大于或等于5元,就必定能够购买成功(即便购买后卡上余额为负),不然没法购买(即便金额足够)。因此你们都但愿尽可能使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可以使卡上的余额为多少。ide
思路:spa
典型的01背包类问题,将余额减去5,就是背包的容量,而后尽量多的往里面装东西。由于能够负的,因此减去的5最后能够买下最贵的菜。设计
题就变成了,去除价格最高后剩下的物品,余额减去5的背包容量,使背包最后剩下的容量最小。rest
得出的这个结果加上5再减去最贵的菜就是答案。code
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define inf 0x3fffffff 4 using namespace std; 5 6 int read(){ 7 int x=0,f=1;char ch=getchar(); 8 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 9 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 10 return x*f; 11 } 12 13 void fre(){ 14 freopen(" .in","r",stdin); 15 freopen(" .out","w",stdout); 16 } 17 18 int n,val[1005],rest,dp[1005]; 19 20 void sce_main(){ 21 for(int i=1;i<=n;i++){ 22 val[i]=read(); 23 }rest=read(); 24 sort(val+1,val+1+n); 25 if(rest<5){ 26 cout<<rest<<endl;return ; 27 } 28 rest-=5; 29 memset(dp,0,sizeof(dp)); 30 for(int i=1;i<=n-1;i++){ 31 for(int j=rest;j>=val[i];j--){ 32 dp[j]=max(dp[j],dp[j-val[i]]+val[i]); 33 } 34 } 35 cout<<rest-dp[rest]+5-val[n]<<endl; 36 } 37 38 int main(){ 39 while(scanf("%d",&n)!=EOF){ 40 if(n==0)return 0; 41 sce_main(); 42 } 43 return 0; 44 }
。。blog
好久没碰博客了,一直再说继续打ACM,可是也只是口号喊得响。get
今天好不容易又开始作题博客
结果发现一道简简单单的01背包问题居然有些作不来了
想要回到之前的水平
任重而道远啊。
不过真好,最近仍是有个好朋友与我一块儿在努力。