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

 /* 3828 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int INF = 0x3f3f3f3f;
const int maxl = ;
const int maxn = ;
const int mod = ;
__int64 a[maxn];
char word[maxn][maxl];
string sw[maxn];
int nxt[maxl];
int Len[maxn];
bool visit[maxn];
int dp[<<][];
int M[][];
int n; void f(char *s, __int64 x) {
int l = ;
while (x) {
s[l] = (x & ) + '';
++l;
x >>= ;
}
s[l] = '\0';
reverse(s, s+l);
} void getnext(char *s) {
int i = , j = -;
int l = strlen(s); nxt[] = -;
while (i < l) {
if (j==- || s[i]==s[j]) {
++i;
++j;
nxt[i] = j;
} else {
j = nxt[j];
}
}
} bool match(char *d, char *s, int ld, int ls) {
int i = , j = ; while (i < ld) {
if (d[i] == s[j]) {
++i;
++j;
} else {
j = nxt[j];
if (j == -) {
j = ;
++i;
}
}
if (j == ls)
return true;
} return false;
} void cover() {
memset(visit, false, sizeof(visit));
rep(i, , n) {
getnext(word[i]);
rep(j, , n) {
if (i == j)
continue;
if (match(word[j], word[i], Len[j], Len[i])) {
visit[i] = true;
break;
}
}
} int nn = ;
rep(i, , n) {
if (!visit[i]) {
strcpy(word[nn], word[i]);
Len[nn] = strlen(word[nn]);
++nn;
}
}
n = nn;
} bool judge(int l, char *sa, char *sb) {
rep(i, , l) {
if (sa[i] != sb[i])
return false;
}
return true;
} int LongFix(int a, int b) {
per(l, , Len[a]) {
if (Len[b]>=l && judge(l, word[a]+Len[a]-l, word[b]))
return l;
} return ;
} void calc() {
rep(i, , n) {
rep(j, , n) {
if (i == j) {
M[i][j] = Len[i];
continue;
}
M[i][j] = LongFix(i, j);
}
}
} void solve() {
sort(a, a+n);
n = unique(a, a+n) - a;
rep(i, , n) {
f(word[i], a[i]);
Len[i] = strlen(word[i]);
}
cover();
calc(); int mst = << n; memset(dp, INF, sizeof(dp));
rep(i, , n)
dp[<<i][i] = Len[i]; rep(i, , mst) {
rep(j, , n) {
if (dp[i][j]==INF || (i&(<<j))==)
continue; rep(k, , n) {
if (i & (<<k))
continue; int nst = i | (<<k);
dp[nst][k] = min(dp[nst][k], dp[i][j]+Len[k]-M[k][j]);
}
}
} rep(i, , n)
sw[i] = string(word[i]); int st = mst - ;
int p = -; string str = "";
while () {
int mn = INF, v;
string tstr, mnstr; rep(i, , n) {
if ((st & (<<i)) == )
continue; int tmp = dp[st][i];
if (p >= ) {
tmp -= M[p][i];
tstr = sw[i].substr(M[p][i]);
} else {
tstr = sw[i];
} if (tmp<mn || (tmp==mn && tstr<mnstr)) {
mn = tmp;
mnstr = tstr;
v = i;
}
} str += mnstr;
p = v;
st ^= ( << v);
if (st == )
break;
} int length = str.length(), base = ;
__int64 ans = ; per(i, , length) {
if (str[i] == '')
ans = (ans + base) % mod;
base = (base + base) % mod;
} printf("%I64d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif while (cin >> n) {
rep(i, , n)
cin >> a[i];
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【HDOJ】3828 A + B problem的更多相关文章

  1. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  2. 【HDOJ】4267 A Simple Problem with Integers

    树状数组.Easy. /* 4267 */ #include <iostream> #include <string> #include <map> #includ ...

  3. 【HDOJ】1016 Prime Ring Problem

    经典DP,写的可能麻烦了一些. #include <stdio.h> #define false 0 #define true 1 ]; ]; ]; void DFS(int, int, ...

  4. 【HDOJ】P2058 The sum problem

    题意很简单就是给你一个N和M,让你求在1-N的那些个子序列的值等于M 首先暴力法不解释,简单超时 再仔细想一想可以想到因为1-N是一个等差数列,可以运用我们曾经学过的只是来解决 假设开始的位置为s,结 ...

  5. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  6. 【CF903G】Yet Another Maxflow Problem 线段树

    [CF903G]Yet Another Maxflow Problem 题意:一张图分为两部分,左边有n个点A,右边有m个点B,所有Ai->Ai+1有边,所有Bi->Bi+1有边,某些Ai ...

  7. 【BZOJ3489】A simple rmq problem

    [BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...

  8. 【BZOJ3489】A simple rmq problem kd-tree

    [BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...

  9. 【题解】CF986E Prince's Problem(树上差分+数论性质)

    [题解]CF986E Prince's Problem(树上差分+数论性质) 题目大意: 给定你一棵树,有点权\(val_i\le 10^7\).现在有\(m\)组询问给定参数\(x,y,w\)问你对 ...

随机推荐

  1. 基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转

    基于css3新属性transform,实现3d立方体的旋转 通过原生JS,点击事件,鼠标按下.鼠标抬起和鼠标移动事件,实现3d立方体的拖动旋转,并将旋转角度实时的反应至界面上显示 实现原理:通过获取鼠 ...

  2. 如何快速建立Subversion服务器

    本文拷贝自网址:http://www.subversion.org.cn/?action-viewnews-itemid-1 如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关 ...

  3. Spark Streaming揭秘 Day21 动态Batch size实现初探(下)

    Spark Streaming揭秘 Day21 动态Batch size实现初探(下) 接昨天的描述,今天继续解析动态Batch size调整的实现. 算法 动态调整采用了Fix-point迭代算法, ...

  4. Oracle 监听动态注册与静态注册

    静态注册 静态注册是在启动listener时,listener会从listener.ora文件中获取服务名及相关信息.信息包括:实例名和服务名等. --静态注册时,listener.ora中的内容如下 ...

  5. 种子填充找连通块 floodfill

    Description Due to recent rains, water has pooled in various places in Farmer John's field, which is ...

  6. iOS sqlite数据库实现(转)

    转载自:http://www.cnblogs.com/macroxu-1982/archive/2012/10/01/2709960.html 1 实现过程添加libsqlite3组件 选择项目后,在 ...

  7. Unity3d之Http通讯GET方法和POST方法

    (一)GET方法 IEnumerator SendGet(string _url) { WWW getData = new WWW(_url); yield return getData; if(ge ...

  8. Mac - 更新 Ruby

    因为准备在项目中使用bootstrap,在安装bootstrap过程中提示需要Ruby的版本在1.9.2以上,而目前使用的Ruby版本是Mac系统自带的1.8.7.所以需要对Ruby进行升级.这里使用 ...

  9. DataTableExtensions.AsEnumerable 方法

    在下面的示例中,DisplayProducts 方法接收一个数据表,其中包含名为 ProductName一个 DataColumn,提取 ProductName 值,然后输出值. using Syst ...

  10. poj 1236 Network of Schools(又是强连通分量+缩点)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...