hdu1864最大报销额(01背包)
http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=187#problem/G
该题要注意的就是每张单子A种类的总和不能大与600,同样B,C类也一样,还有注意如果不是A,B,C类的不可以报销;
该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。
这题考的背包很简单,就是输入的金额为背包的容积,债券既是物体的体积又是物体的利润。就是处理输入的数据有点麻烦,这是我所不擅长的。
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> int dp[3000001],w[31]; int main() { int n,V,m,flag,tt; double sum,price; char c; while(scanf("%lf%d",&sum,&n)!=EOF) { if(n==0) break; sum=sum*100; V=(int)sum; tt=0; int t,ta=0,tb=0,tc=0,x; for(int i=1;i<=n;i++) { sum=0; ta=0,tb=0,tc=0; scanf("%d",&m); flag=0; while(m--) { scanf("%*c%c:%lf",&c,&price); price=price*100; x=(int)price; if(flag==0) { if((c=='A')||(c=='B')||(c=='C')) { if(c=='A'&&ta+x<=60000) { ta=ta+x; } else if(c=='B'&&tb+x<=60000) { tb=tb+x; } else if(c=='C'&&tc+x<=60000) { tc=tc+x; } else flag=1; } else flag=1; } } t=ta+tb+tc; if(flag==0&&t<=100000) { w[tt++]=t; } } memset(dp,0,sizeof(dp)); for(int i=0;i<tt;i++) { for(int j=V;j>=w[i];j--) { if(dp[j-w[i]]+w[i]>dp[j]) dp[j]=dp[j-w[i]]+w[i]; } } double money=dp[V]/100.0; printf("%.2lf\n",money); } return 0; }