【HDOJ】3828 A + B problem
显然需要贪心,重叠越长越好,这样最终的串长尽可能短。
需要注意的是,不要考虑中间结果,显然是个状态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的更多相关文章
- 【HDOJ】4729 An Easy Problem for Elfness
其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...
- 【HDOJ】4267 A Simple Problem with Integers
树状数组.Easy. /* 4267 */ #include <iostream> #include <string> #include <map> #includ ...
- 【HDOJ】1016 Prime Ring Problem
经典DP,写的可能麻烦了一些. #include <stdio.h> #define false 0 #define true 1 ]; ]; ]; void DFS(int, int, ...
- 【HDOJ】P2058 The sum problem
题意很简单就是给你一个N和M,让你求在1-N的那些个子序列的值等于M 首先暴力法不解释,简单超时 再仔细想一想可以想到因为1-N是一个等差数列,可以运用我们曾经学过的只是来解决 假设开始的位置为s,结 ...
- 【BZOJ3489】A simple rmq problem(KD-Tree)
[BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
- 【CF903G】Yet Another Maxflow Problem 线段树
[CF903G]Yet Another Maxflow Problem 题意:一张图分为两部分,左边有n个点A,右边有m个点B,所有Ai->Ai+1有边,所有Bi->Bi+1有边,某些Ai ...
- 【BZOJ3489】A simple rmq problem
[BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...
- 【BZOJ3489】A simple rmq problem kd-tree
[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...
- 【题解】CF986E Prince's Problem(树上差分+数论性质)
[题解]CF986E Prince's Problem(树上差分+数论性质) 题目大意: 给定你一棵树,有点权\(val_i\le 10^7\).现在有\(m\)组询问给定参数\(x,y,w\)问你对 ...
随机推荐
- Projected Coordinate Systems
Coordinate Systems Projected Coordinate Systems This is an archive of a previous version of the ArcG ...
- 【CLR VIA C#】读书笔记
工作几年了才看,记录下笔记备忘. 章节 笔记 1.CLR的执行模型 公共语言运行时(Common Language Runtime,CLR) 源代码-->编译器检查语法和分析源代码-->托 ...
- Ajax的理解
初学JS,一直认为Ajax是个很高级的.不可亵玩的东西.这两天怀着忐忑的心情接触了一下它, 感觉它并没有想象中的那么难理解. 其实,Ajax就是浏览器端向服务器请求资源的一个对象(方法). 就跟打电话 ...
- String Subtraction
Given two strings S1 and S2, S = S1 - S2 is defined to be the remaining string after taking all the ...
- 种子填充找连通块 floodfill
Description Due to recent rains, water has pooled in various places in Farmer John's field, which is ...
- javascript看你能够做对几题
http://ourjs.com/detail/52fb82e13bd19c4814000001
- Perl内置变量速查表
[ 文件句柄 ] $| 如果非零, 则在对当前选定的文件执行写或打印操作后强制清除缓冲区 $% 当前选中文件句柄的当前页码 $= 当前选中文件句柄的当前页面长度 $- 当前选中文件句柄的页面剩余长度 ...
- easy ui 表单提交添加遮罩,避免数据重复提交
如下图: //点击提交按钮保存数据 $('#btn_submit').click(function () { //增加遮罩层 $.messager.progress({ title: '温馨提示', ...
- MyBatis对不同数据库的主键生成策略
本文转自:http://289972458.iteye.com/blog/1001851 http://hi.baidu.com/zim_it/blog/item/8a2bd11205f5b56ec ...
- WDS无线桥接
因为放假回家,长时间不在家,家里也没什么人,所以也就没有网可以用.为了两个月办宽带又不值得,太过浪费了.于是就只能蹭网用了.当然,要和邻居打个招呼或者你能搞定密码的情况下不打招呼(嘿嘿...).但是有 ...