题意:
给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 ", x);} 27 #define pd(x) {printf("%.7lf ", 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 ", ++ kcase); 82 printf("Maximum profit is %d. ", 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(" "); 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(" "); 100 read(); 101 solve(); 102 } 103 return 0; 104 }