[POJ1416]Shredding Company(dfs or 状压枚举)

题目链接:http://poj.org/problem?id=1416

题意:一段数分成好几段相加,求最大的且不大于目标值的组合。

DFS,用vector<int>tmp来记录中间结果,回溯的时候pop掉。判重用了个map,其实用一个flag打标记也可。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <cassert>
 8 #include <cstdio>
 9 #include <bitset>
10 #include <vector>
11 #include <deque>
12 #include <queue>
13 #include <stack>
14 #include <ctime>
15 #include <set>
16 #include <map>
17 #include <cmath>
18 
19 using namespace std;
20 
21 const int maxn = 32;
22 int digit[maxn];
23 map<int,int> vis;
24 int n, aim;
25 int len, ret;
26 vector<int> ans, tmp;
27 
28 int sum(int x, int y) {
29   int ret = 0;
30   while(x <= y) {
31     ret *= 10;
32     ret += digit[x++];
33   }
34   return ret;
35 }
36 
37 void dfs(int cur, int pos) {
38     if(cur > aim) return;
39     if(pos > len) {
40         if(cur <= aim) {
41             if(ret <= cur) {
42                 ret = cur; vis[ret]++;
43                 ans.clear();
44                 for(int i = 0; i < tmp.size(); i++) {
45                     ans.push_back(tmp[i]);
46                 }
47             }
48         }
49         return;
50     }
51     for(int i = pos; i <= len; i++) {
52         int x = sum(pos, i);
53         tmp.push_back(x);
54         dfs(cur+x, i+1);
55         tmp.pop_back();
56     }
57 }
58 
59 void f(int x) {
60   len = 0;
61     vector<int> s;
62   while(x) {
63         s.push_back(x%10);
64     x /= 10;
65   }
66     for(int i = s.size() - 1; i >= 0; i--) {
67         digit[++len] = s[i];
68     }
69     tmp.clear();
70     dfs(0, 1);
71 }
72 
73 int main() {
74 //  freopen("in", "r", stdin);
75   while(~scanf("%d%d",&aim,&n)&&aim+n) {
76         if(aim >= n) {
77             printf("%d %d
",n, n);
78             continue;
79         }
80     ret = -1; vis.clear();
81     f(n);
82     if(ret == -1) puts("error");
83     else if(vis[ret] >= 2) puts("rejected");
84     else {
85             printf("%d ", ret);
86             for(int i = 0; i < ans.size(); i++) {
87         if(i) printf(" ");
88         printf("%d", ans[i]);
89       }
90       printf("
");
91     }
92   }
93   return 0;
94 }

状压枚举也可以

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <cassert>
 8 #include <cstdio>
 9 #include <bitset>
10 #include <vector>
11 #include <deque>
12 #include <queue>
13 #include <stack>
14 #include <ctime>
15 #include <set>
16 #include <map>
17 #include <cmath>
18 using namespace std;
19 
20 const int maxn = 32;
21 int digit[maxn];
22 int n, m, len, ret;
23 bool dump;
24 vector<int> tmp, ans;
25 
26 void f(int x) {
27     len = 0; tmp.clear();
28     while(x) {
29         tmp.push_back(x % 10);
30         x /= 10;
31     }
32     for(int i = int(tmp.size())-1; i >= 0; i--) {
33         digit[len++] = tmp[i];
34     }
35 }
36 
37 void get(vector<int>& tmp, int sta, int& sum) {
38     int cur = 0, flag = 0;
39     tmp.clear(); sum = 0;
40     cur = digit[0];
41     flag = sta % 2; sta >>= 1;
42     for(int i = 1; i < len; i++, sta>>=1) {
43         if(sta % 2 == flag) {
44             cur = cur * 10 + digit[i];
45         }
46         else {
47             flag = !flag;
48             tmp.push_back(cur); sum += cur;
49             cur = digit[i];
50         }
51     }
52     tmp.push_back(cur); sum += cur;
53 }
54 
55 int main() {
56 //    freopen("in", "r", stdin);
57     while(~scanf("%d%d",&n,&m) && n+m) {
58         f(m); dump = 0; ans.clear(); ret = -1;
59         int mm = 1 << len, sum;
60         mm >>= 1;
61         for(int sta = 0; sta < mm; sta++) {
62             get(tmp, sta, sum);
63             if(sum > n) continue;
64             if(sum > ret) {
65                 ret = sum; dump = 0;
66                 ans = tmp;
67             }
68             else if(sum == ret) dump = 1;
69         }
70         if(!~ret) puts("error");
71         else if(dump) puts("rejected");
72         else {
73             printf("%d", ret);
74             for(int i = 0; i < ans.size(); i++) {
75                 printf(" %d", ans[i]);
76             }
77             printf("
");
78         }
79     }
80     return 0;
81 }
原文地址:https://www.cnblogs.com/kirai/p/5941517.html