- 题目描述:
-
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
- 输入:
-
测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(N<=30)是发票张数。随后是 N 行输入,每行的格式为:
m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
- 输出:
-
对每个测试用例输出1行,即可以报销的最大数额,精确到小数点后2位。
- 样例输入:
-
200.00 3 2 A:23.50 B:100.00 1 C:650.00 3 A:59.99 A:120.00 X:10.00 1200.00 2 2 B:600.00 A:400.00 1 C:200.50 1200.50 3 2 B:600.00 A:400.00 1 C:200.50 1 A:100.00 100.00 0
- 样例输出:
-
123.50 1000.00 1200.50
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 7 #define NMAX 32 8 #define MAX 1000 9 10 struct Good 11 { 12 char type; 13 double price; 14 }; 15 16 Good fa[NMAX][MAX]; 17 double cost[MAX]; 18 double weight[MAX]; 19 char temp[MAX]; 20 21 double dp[1000002]; 22 23 int max(double a, double b) { 24 if(a > b) { 25 return a; 26 } 27 else { 28 return b; 29 } 30 } 31 32 int main(int argc, char const *argv[]) 33 { 34 double Q; 35 int N; 36 //freopen("input.txt","r",stdin); 37 scanf("%lf %d",&Q,&N); 38 while(N != 0) { 39 int m; 40 int k = 0; 41 for(int i = 0; i < N; i++) { 42 scanf("%d",&m); 43 double sumi = 0; 44 bool flag = false; 45 for(int j = 0; j < m; j++) { 46 scanf("%s",temp); 47 sscanf(temp,"%c:%lf",&fa[i][j].type, &fa[i][j].price); 48 if(flag == false) { 49 if(fa[i][j].type != 'A' && fa[i][j].type != 'B' && fa[i][j].type != 'C') { 50 flag = true; 51 } 52 else { 53 if(fa[i][j].price > 600) { 54 flag = true; 55 } 56 else { 57 if(sumi > 1000 || sumi > Q) { 58 flag = true; 59 } 60 else { 61 sumi = sumi + fa[i][j].price; 62 } 63 } 64 } 65 66 } 67 }///for(int j) 68 69 if(flag == false) { 70 cost[k] = sumi; 71 k++; 72 } 73 }//for(int i) 74 75 int q = Q * 100; 76 memset(dp, 0, sizeof(dp)); 77 78 for(int i = 0; i < k; i++) { 79 for(int j = q; j >= (int)(cost[i]*100); j--) { 80 dp[j] = max(dp[j],dp[j-(int)(cost[i]*100)]+ 100*cost[i]); 81 if(i == k-1) { 82 break; 83 } 84 } 85 } 86 printf("%.2lf ",dp[q]/100.0); 87 scanf("%lf %d",&Q,&N); 88 89 } 90 return 0; 91 }
这道题一开始使我觉得要做出来十分困难,主要是不知道如何处理容量为小数的背包问题,最后用了变通的办法,乘了100来解决,没想到居然通过了