hdu_1864

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864

DP题目,背包问题,我们的背包容量为输入的Q,物品的数目使我们输入的N,需要注意的有3个点:

1)物品的种类只能是A、B、C,其他的物品不予报销

2)单个物品种类不能超过600

3)单张发票上可以有多个种类,但是不能超过1000

考虑到这些,注意一些需要处理的细节,如字符的处理等,采用DP策略即可。置初始化dp[0] = 0,表示都没有报销,外层循环遍历后续的发票,内层循环遍历当前发票之前的发票,判定如果报销发票满足输入能报销的最大额,就加上。最后遍历一遍DP数组,取最大值便是最优解。代码如下:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<string.h>
 5 //#include<bits/stdc++.h>
 6 const int maxn = 35;
 7 using namespace std;
 8 
 9 int main(){
10     int i,j,n,num,flag,cnt;
11     double dp[maxn],m[maxn];
12     char str,b;
13     double w,f;
14     double A,B,C,MAX;
15     while(cin >> w >> n && n){
16         memset(dp,0,sizeof(dp));
17         cnt = 1;
18         for(i = 0; i < n; i++){
19             flag = 0;
20             A = 0;
21             B = 0;
22             C = 0;
23             cin >> num;
24             for(j = 0; j < num; j++){
25                 cin >> str >> b >> f;
26                 if(str == 'A'){
27                     A += f;
28                 }
29                 else if(str == 'B'){
30                     B += f;
31                 }
32                 else if(str == 'C'){
33                     C += f;
34                 }
35                 else{
36                     flag = 1;
37                 }
38             }
39             if(!flag && A <= 600 && B <= 600 && C <= 600 && A+B+C <= 1000){
40                 m[cnt++] = A+B+C;
41             }
42         }
43         for(i = 1; i < cnt; i++){
44             for(j = i-1; j >= 0; j--){
45                 if(dp[j]+m[i] <= w){
46                     dp[i] = max(dp[j]+m[i],dp[i]);
47                 }
48             }
49         }
50         MAX = 0;
51         for(i = 0; i < cnt; i++){
52             if(dp[i] > MAX){
53                 MAX = dp[i];
54             }
55         }
56         printf("%.2lf\n",MAX);
57     }
58     return 0;
59 }

 

posted @ 2018-09-05 19:21  琥琥笙威  阅读(114)  评论(0编辑  收藏  举报