HDU-1864 最大报销额
题意:
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
分析:
一眼看上来是背包,再看不对,是小数,没法用数组表示状态,再看,还是背包!小数点后两位,那么只要把数乘100然后该怎么跑背包怎么跑就可以惹~
emmm需要用滚动数组不然会MLE的
另外这里有坑是,一张发票中同一种类型的属于一个···
对惹,看到网上很多非背包的题解很多都是错的··因为数据弱可以水过去···
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int maxn=50; 7 const int maxs=3000000+10; 8 struct Node{ 9 int num; 10 bool vis; 11 }node[maxn]; 12 double ans; 13 double q; 14 int n; 15 int k; 16 int f[maxs]; 17 bool judge=0; 18 int main(){ 19 while(scanf("%lf%d",&q,&n)!=EOF&&n){ 20 if(!n)return 0; 21 ans=0; 22 for(int i=1;i<=n;i++){ 23 scanf("%d",&k); 24 double sum=0; 25 char c; 26 double a; 27 bool ok=1; 28 int A=0,B=0,C=0; 29 for(int j=1;j<=k;j++){ 30 scanf(" %c:%lf",&c,&a); 31 if(c=='A')A+=a; 32 if(c=='B')B+=a; 33 if(c=='C')C+=a; 34 if((c!='A'&&c!='B'&&c!='C')||(a>600)) 35 ok=0; 36 sum+=a; 37 } 38 if(A>600||B>600||C>600)ok=0; 39 if(sum>1000)ok=0; 40 node[i].num=sum*100; 41 node[i].vis=ok; 42 } 43 memset(f,0,sizeof(f)); 44 for(int i=1;i<=n;i++){ 45 for(int j=q*100;j>=0;j--){ 46 if(node[i].vis&&j>=node[i].num){ 47 f[j]=max(f[j],f[j-node[i].num]+node[i].num); 48 } 49 } 50 } 51 int sec=q*100; 52 ans=f[sec]/100.0; 53 printf("%.2f\n",ans); 54 } 55 return 0; 56 }