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
",ans);
54     }
55     return 0;
56 }
View Code
原文地址:https://www.cnblogs.com/LQLlulu/p/8784553.html