题意:
给w个货架, 每个货架上有bi个货物, 每次只能拿最上面的货物, 每个货物有个价值, 所有货物的售价均为10。
问:能获得的最大利润, 以及能获得这个利润需要多少个货物。 (有多种组合时只需输出前10种)
思路:
最开始我是先将最大价值预处理了出来, 然后dfs查找方案数, 结果超时了, 后来发现复杂度是O(w*bi), 完全的暴力,可以先将每个货架的最大利润处理出来, 同时处理出来获得这个最大利润所需要的物品数。
后来又WA了几发, 第一次是发现自己没有处理如果利润为负时, 结果应该输出0的情况。
第二次发现没有处理某个货架最大利润为0时可以一个都不取的情况。
代码:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <stack>
10 #include <queue>
11 #include <string>
12 #include <vector>
13 #include <fstream>
14 #include <iterator>
15 #include <iostream>
16 #include <algorithm>
17 using namespace std;
18 #define LL long long
19 #define INF 0x3f3f3f3f
20 #define MOD 1000000007
21 #define eps 1e-6
22 #define MAXN 100
23 #define MAXM 30
24 #define dd {cout<<"debug"<<endl;}
25 #define pa {system("pause");}
26 #define p(x) {printf("%d\n", x);}
27 #define pd(x) {printf("%.7lf\n", x);}
28 #define k(x) {printf("Case %d: ", ++x);}
29 #define s(x) {scanf("%d", &x);}
30 #define sd(x) {scanf("%lf", &x);}
31 #define mes(x, d) {memset(x, d, sizeof(x));}
32 #define do(i, x) for(i = 0; i < x; i ++)
33 #define dod(i, x, l) for(i = x; i >= l; i --)
34 #define doe(i, x) for(i = 1; i <= x; i ++)
35 int w;
36 int f[MAXN][MAXM];
37 int max_ans, kcase = 0;
38 set <int> ans;
39 vector <int> g[MAXN];
40 void read()
41 {
42 max_ans = 0;
43 for(int i = 0; i < w; i ++)
44 {
45 scanf("%d", &f[i][0]);
46
47 int sum = 0;
48 int max_tmp = 0;
49 g[i].clear();
50 for(int j = 1; j <= f[i][0]; j ++)
51 {
52 scanf("%d", &f[i][j]);
53 f[i][j] = 10 - f[i][j];
54 sum += f[i][j];
55 if(sum > max_tmp)
56 {
57 max_tmp = sum;
58 g[i].clear();
59 }
60 if(sum == max_tmp)
61 g[i].push_back(j);
62 }
63 if(g[i].empty() || max_tmp == 0) g[i].push_back(0); //!!!
64 max_ans += max_tmp;
65 }
66 }
67 void dfs(int pos, int num)
68 {
69 if(pos == w)
70 {
71 ans.insert(num);
72 return ;
73 }
74
75 for(int i = 0; i < g[pos].size(); i ++)
76 dfs(pos + 1, num + g[pos][i]);
77 }
78 void show()
79 {
80 int cnt = 0;
81 printf("Workyards %d\n", ++ kcase);
82 printf("Maximum profit is %d.\n", max_ans);
83 printf("Number of pruls to buy:");
84 for(set <int>::iterator it = ans.begin(); it != ans.end() && cnt < 10; it ++, cnt ++)
85 printf(" %d", *it);
86 printf("\n");
87 }
88 void solve()
89 {
90 ans.clear();
91 dfs(0, 0);
92 show();
93 }
94
95 int main()
96 {
97 while(scanf("%d", &w) && w)
98 {
99 if(kcase) printf("\n");
100 read();
101 solve();
102 }
103 return 0;
104 }