电商网站建设重要性,中国建筑设计咨询公司,非主营电子商务企业网站有哪些,手机网站app制作公司正题
题面链接:https://www.luogu.com.cn/problem/U142584 题目大意 nnn个010101串#xff0c;按顺序分成两个序列#xff0c;然后拼接成一个序列#xff08;拼接串x,yx,yx,y的话就是变成一个前缀包含xxx#xff0c;后缀包含yyy的最短的串#xff09;。求最短长度。 解题…正题
题面链接:https://www.luogu.com.cn/problem/U142584 题目大意
nnn个010101串按顺序分成两个序列然后拼接成一个序列拼接串x,yx,yx,y的话就是变成一个前缀包含xxx后缀包含yyy的最短的串。求最短长度。 解题思路
显然将010101串的状态压起来 定义prex,ipre_{x,i}prex,i表示串xxx的前iii位sufx,isuf_{x,i}sufx,i表示串xxx的后iii位comx,ycom_{x,y}comx,y表示串x,yx,yx,y的最长公共位。 那么设fi,j,kf_{i,j,k}fi,j,k表示到第iii个串第一个串以aia_iai结尾第二个的后jjj位是kkk时的最小长度和。 那么第一种转移就是拼接ai−1a_{i-1}ai−1和aia_iai也就是fi,j,kfi−1,j,kL−comai−1,aif_{i,j,k}f_{i-1,j,k}L-com_{a_{i-1},a_i}fi,j,kfi−1,j,kL−comai−1,ai 第二种是aia_iai和kkk拼起来那么第一个串的kkk就变成了ai−1a_{i-1}ai−1 fi,j,suf(ai−1,j)fi−1,j,pre(ai,j)L−jf_{i,j,suf(a_{i-1},j)}f_{i-1,j,pre(a_i,j)}L-jfi,j,suf(ai−1,j)fi−1,j,pre(ai,j)L−j
这样转移是O(n∗l∗2l)O(n*l*2^l)O(n∗l∗2l)的显然无法通过本题
发现主要的时间落在第一个转移上我们考虑优化掉第一个转移我们发现每次的L−comai−1,aiL-com_{a_{i-1},a_i}L−comai−1,ai是一个定值我们可以先让最后的答案加上这些定值然后第一个转移可以去掉二个转移变为fi,j,suf(ai−1,j)fi−1,j,pre(ai,j)comai−1,ai−jf_{i,j,suf(a_{i-1},j)}f_{i-1,j,pre(a_i,j)}com_{a_{i-1},a_i}-jfi,j,suf(ai−1,j)fi−1,j,pre(ai,j)comai−1,ai−j
时间复杂度O(n∗l)O(n*l)O(n∗l) codecodecode
#includecstdio
#includecstring
#includealgorithm
using namespace std;
const int N2e510,inf2147483647/3;
int n,L,a[N],f[21][121],ans;
char s[N];
int pre(int x,int i)
{return x(L-i);}
int suf(int x,int i)
{return x((1i)-1);}
int com(int x,int y){for(int iL;i0;i--)if(suf(x,i)pre(y,i))return i;
}
int main()
{scanf(%d,n);for(int i1;in;i){scanf(%s,s);if(i1)Lstrlen(s);for(int j0;jL;j)a[i](a[i]1)(s[j]-0);}memset(f,0x3f,sizeof(f));f[0][0]L;for(int i2;in;i){int tmpL-com(a[i-1],a[i]),minsinf;anstmp;for(int j0;jL;j)minsmin(mins,f[j][pre(a[i],j)]L-j-tmp);for(int j0;jL;j)f[j][suf(a[i-1],j)]min(f[j][suf(a[i-1],j)],mins);}printf(%d\n,f[0][0]ans);
}