【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] = '\0';
 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\n", 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.\n", (int)clock());
256     #endif
257     
258     return 0;
259 }

 

posted on 2016-01-24 21:45  Bombe  阅读(174)  评论(0编辑  收藏  举报

导航