zoukankan      html  css  js  c++  java
  • 【HDOJ】3828 A + B problem

    显然需要贪心,重叠越长越好,这样最终的串长尽可能短。
    需要注意的是,不要考虑中间结果,显然是个状态dp。
    先做预处理去重,然后求任意一对串的公共长度。

      1 /* 3828 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <bitset>
     12 #include <algorithm>
     13 #include <cstdio>
     14 #include <cmath>
     15 #include <ctime>
     16 #include <cstring>
     17 #include <climits>
     18 #include <cctype>
     19 #include <cassert>
     20 #include <functional>
     21 #include <iterator>
     22 #include <iomanip>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,1024000")
     25 
     26 #define sti                set<int>
     27 #define stpii            set<pair<int, int> >
     28 #define mpii            map<int,int>
     29 #define vi                vector<int>
     30 #define pii                pair<int,int>
     31 #define vpii            vector<pair<int,int> >
     32 #define rep(i, a, n)     for (int i=a;i<n;++i)
     33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     34 #define clr                clear
     35 #define pb                 push_back
     36 #define mp                 make_pair
     37 #define fir                first
     38 #define sec                second
     39 #define all(x)             (x).begin(),(x).end()
     40 #define SZ(x)             ((int)(x).size())
     41 #define lson            l, mid, rt<<1
     42 #define rson            mid+1, r, rt<<1|1
     43 
     44 
     45 const int INF = 0x3f3f3f3f;
     46 const int maxl = 70;
     47 const int maxn = 16;
     48 const int mod = 1000000009;
     49 __int64 a[maxn];
     50 char word[maxn][maxl];
     51 string sw[maxn];
     52 int nxt[maxl];
     53 int Len[maxn];
     54 bool visit[maxn];
     55 int dp[1<<16][16];
     56 int M[16][16];
     57 int n;
     58 
     59 void f(char *s, __int64 x) {
     60     int l = 0;
     61     while (x) {
     62         s[l] = (x & 1) + '0';
     63         ++l;
     64         x >>= 1;
     65     }
     66     s[l] = '';
     67     reverse(s, s+l);
     68 }
     69 
     70 void getnext(char *s) {
     71     int i = 0, j = -1;
     72     int l = strlen(s);
     73     
     74     nxt[0] = -1;
     75     while (i < l) {
     76         if (j==-1 || s[i]==s[j]) {
     77             ++i;
     78             ++j;
     79             nxt[i] = j;
     80         } else {
     81             j = nxt[j];
     82         }
     83     }
     84 }
     85 
     86 bool match(char *d, char *s, int ld, int ls) {
     87     int i = 0, j = 0;
     88     
     89     while (i < ld) {
     90         if (d[i] == s[j]) {
     91             ++i;
     92             ++j;
     93         } else {
     94             j = nxt[j];
     95             if (j == -1) {
     96                 j = 0;
     97                 ++i;
     98             }
     99         }
    100         if (j == ls)
    101             return true;
    102     }
    103     
    104     return false;
    105 }
    106 
    107 void cover() {
    108     memset(visit, false, sizeof(visit));
    109     rep(i, 0, n) {
    110         getnext(word[i]);
    111         rep(j, 0, n) {
    112             if (i == j)
    113                 continue;
    114             if (match(word[j], word[i], Len[j], Len[i])) {
    115                 visit[i] = true;
    116                 break;
    117             }
    118         }
    119     }
    120     
    121     int nn = 0;
    122     rep(i, 0, n) {
    123         if (!visit[i]) {
    124             strcpy(word[nn], word[i]);
    125             Len[nn] = strlen(word[nn]);
    126             ++nn;
    127         }
    128     }
    129     n = nn;
    130 }
    131 
    132 bool judge(int l, char *sa, char *sb) {
    133     rep(i, 0, l) {
    134         if (sa[i] != sb[i])
    135             return false;
    136     }
    137     return true;
    138 }
    139 
    140 int LongFix(int a, int b) {
    141     per(l, 1, Len[a]) {
    142         if (Len[b]>=l && judge(l, word[a]+Len[a]-l, word[b]))
    143             return l;
    144     }
    145 
    146     return 0;
    147 }
    148 
    149 void calc() {
    150     rep(i, 0, n) {
    151         rep(j, 0, n) {
    152             if (i == j) {
    153                 M[i][j] = Len[i];
    154                 continue;
    155             }
    156             M[i][j] = LongFix(i, j);
    157         }
    158     }
    159 }
    160 
    161 void solve() {
    162     sort(a, a+n);
    163     n = unique(a, a+n) - a;
    164     rep(i, 0, n) {
    165         f(word[i], a[i]);
    166         Len[i] = strlen(word[i]);
    167     }
    168     cover();
    169     calc();
    170     
    171     int mst = 1 << n;
    172     
    173     memset(dp, INF, sizeof(dp));
    174     rep(i, 0, n)
    175         dp[1<<i][i] = Len[i];
    176         
    177     rep(i, 0, mst) {
    178         rep(j, 0, n) {
    179             if (dp[i][j]==INF || (i&(1<<j))==0)
    180                 continue;
    181             
    182             rep(k, 0, n) {
    183                 if (i & (1<<k))
    184                     continue;
    185                 
    186                 int nst = i | (1<<k);
    187                 dp[nst][k] = min(dp[nst][k], dp[i][j]+Len[k]-M[k][j]);
    188             }
    189         }
    190     }
    191     
    192     rep(i, 0, n)
    193         sw[i] = string(word[i]);
    194         
    195     int st = mst - 1;
    196     int p = -1;
    197     
    198     string str = "";
    199     while (1) {
    200         int mn = INF, v;
    201         string tstr, mnstr;
    202         
    203         rep(i, 0, n) {
    204             if ((st & (1<<i)) == 0)
    205                 continue;
    206             
    207             int tmp = dp[st][i];
    208             if (p >= 0) {
    209                 tmp -= M[p][i];
    210                 tstr = sw[i].substr(M[p][i]);
    211             } else {
    212                 tstr = sw[i];
    213             }
    214             
    215             if (tmp<mn || (tmp==mn && tstr<mnstr)) {
    216                 mn = tmp;
    217                 mnstr = tstr;
    218                 v = i;
    219             }
    220         }
    221         
    222         str += mnstr;
    223         p = v;
    224         st ^= (1 << v);
    225         if (st == 0)
    226             break;
    227     }
    228     
    229     int length = str.length(), base = 1;
    230     __int64 ans = 0;
    231     
    232     per(i, 0, length) {
    233         if (str[i] == '1')
    234             ans = (ans + base) % mod;
    235         base = (base + base) % mod;
    236     }
    237     
    238     printf("%I64d
    ", ans);
    239 }
    240 
    241 int main() {
    242     ios::sync_with_stdio(false);
    243     #ifndef ONLINE_JUDGE
    244         freopen("data.in", "r", stdin);
    245         freopen("data.out", "w", stdout);
    246     #endif
    247     
    248     while (cin >> n) {
    249         rep(i, 0, n)
    250             cin >> a[i];
    251         solve();
    252     }
    253     
    254     #ifndef ONLINE_JUDGE
    255         printf("time = %d.
    ", (int)clock());
    256     #endif
    257     
    258     return 0;
    259 }
  • 相关阅读:
    事件委托
    a标签深入研究
    windows查看端口号
    什么是WCM
    map key循环
    用Myeclipse打war包
    myeclipse 8.510.0 安装 svn 方法
    SVN使用&CVS使用
    MyEclipse 字体大小 字体颜色
    什么是Quickr
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5156063.html
Copyright © 2011-2022 走看看