• [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 }
  • 相关阅读:
    gRPC实战
    深入浅出docker
    jquery操作复选框(checkbox)的12个小技巧总结
    System.Diagnostics.Process.Start的妙用
    Redis持久化数据丢失及解决
    【ASP.NET 问题】IIS发布网站后出现 "处理程序“PageHandlerFactoryIntegrated”在其模块列表中有一个错误"的解决办法
    asp.net 网页抓取内容
    Ajax学习资源大全[本来是转载的,但是现在我增加了很多]
    jquery如何判断checkbox(复选框)是否被选中
    JS获取屏幕高度
  • 原文地址:https://www.cnblogs.com/kirai/p/5941517.html
Copyright © 2020-2023  润新知