[bzoj1195][HNOI2006]最短母串_動態規劃_狀壓dp
阿新 • • 發佈:2018-07-22
字典 數據 n) 求一個 表示 n! 規劃 esp zoj
最短母串 bzoj-1195 HNOI-2006
題目大意:給一個包含n個字符串的字符集,求一個字典序最小的字符串使得字符集中所有的串都是該串的子串。
註釋:$1\le n\le 12$,$1\le max length \le 50$。
想法:剛開始在那裏AC自動機半天,然後瞅了一眼數據範圍... ...狀壓吧兄弟!!
首先,我們先做一些預處理:把可以被字符集中串包含的串都刪掉;求出兩個字符串連接後的長度(這個預處理暴力即可),設merge[i][j]表示串i和串j合並後的長度。
狀態:dp[s][i]表示這個串已經包含了s狀態的字符串且緊跟著的串是i的最短長度。
轉移:dp[s][i]=min{dp[s^(1<<(j+1))][j]+merge[i][j]-length(j)};
最後,附上醜陋的代碼... ...
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int mxn=61; int n; struct bind { char s[605]; int len; bool operator < (const bind y) const { if(len!=y.len)return len<y.len; for(int i=0;i<len;i++) if(s[i]!=y.s[i])return s[i]<y.s[i]; return 0; } }f[1<<12][12],s[12]; int c[13][13]; bool ban[mxn]; bool ovl(int i,int j) { if(s[i].len<s[j].len)return 0; char *p=strstr(s[i].s,s[j].s); if(p==NULL)return 0; return 1; } int clc(int x,int y) { bool flag=0; for(int i=max(0,s[x].len-s[y].len);i<s[x].len;i++) { flag=1; for(int j=i;j<s[x].len;j++) if(s[x].s[j]!=s[y].s[j-i]){flag=0;break;} if(flag)return s[x].len-i; } return 0; } bind merge(int S,int u,int v) { bind tmp=f[S][u]; strcat(tmp.s,s[v].s+c[u][v]); tmp.len=f[S][u].len-c[u][v]+s[v].len; return tmp; } void Dp() { int i,j,ed=(1<<n)-1; for(i=0;i<=ed;i++) for(j=0;j<n;j++)f[i][j].len=INF; for(i=0;i<n;i++)f[1<<i][i]=s[i]; for(i=1;i<=ed;i++) { for(j=0;j<n;j++) { if((i>>j)&1) for(int k=0;k<n;k++) { if((i>>k)&1) continue; bind tmp=merge(i,j,k); if(tmp<f[i|(1<<k)][k])f[i|(1<<k)][k]=tmp; } } } } int main() { scanf("%d",&n); for(int i=0;i<n;i++)scanf("%s",s[i].s),s[i].len=strlen(s[i].s); for(int i=0;i<n;i++) for(j=0;j<n;j++) if(i!=j && ovl(i,j) && !ban[i])ban[j]=1; int cnt=0; for(int i=0;i<n;i++)if(!ban[i])s[cnt++]=s[i]; n=cnt; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j)c[i][j]=clc(i,j); Dp(); int ans=0,ed=(1<<n)-1; for(int i=1;i<n;i++) if(f[ed][i]<f[ed][ans])ans=i; printf("%s",f[ed][ans].s); return 0; }
小結:看到了數據做題是一種解題想法,但是考試的時候看數據範圍猜復雜度我tm就沒成功過... ...
[bzoj1195][HNOI2006]最短母串_動態規劃_狀壓dp