習題 最短母串(狀壓)

2021-09-25 15:50:25 字數 1275 閱讀 9838

題目:

記憶體限制:512 mib時間限制:1000 ms標準輸入輸出

題目型別:傳統評測方式:文字比較

題目描述

給定n  個字串 ,要求找到乙個最短的字串 ,使得這  n個字串都是它  的子串。

輸入格式

第一行是乙個正整數 ,表示給定的字串的個數;

以下的 n+1 行,每行有乙個全由大寫字母組成的字串。

輸出格式

只有一行,為找到的最短的字串 。

在保證最短的前提下,如果有多個字串都滿足要求,那麼必須輸出按字典序排列的第乙個。

n<=12    1<=|s[i]|<=50

樣例樣例輸入

2 

abcd

bcdabc

樣例輸出

abcdabc

思路:看到n這麼小,首先考慮的就是搜尋或者狀壓,但是搜尋的話,就的是所有字串的全排列,即使加一些減枝,

時間複雜度依舊不可承受。

那麼考慮狀壓,狀態設計自然就是dp[i][j],狀態為i的串以j結尾的最小母串。

對狀態為i進行解釋:將i轉換成二進位制之後每一位上的值,0代表不選,1代表選

狀態的轉移也很簡單,就是列舉接在j之後的子串

同時定義乙個g[i][j],表示dp[i][j]的字串

最後統計一下g[i][j]就行了

對於兩個字串,我們只需考慮從哪一位開始重複即可知道重複的部分是多少,

同時考慮到此陣列可能多次使用,因此採用離線來降低時間複雜度

總時間複雜度為(n*2^n)

**

#include#include#include#includeusing namespace std;

int n;

int minn=int_max;

int overlap[15][15];//j接到i號字串之後

int dp[5000][15];//狀態為i且已j號字串結尾,1為選擇,0為不選擇

int top=0;

string g[5000][15];//在狀態為i且以j號字串結尾的結果

string a[15];

string ans;

void solve(int x,int y)}}

}}}}

/*for(int i=0;i<(1

for(int i=1;i<=n;i++)

else if(dp[(1<}

cout

}

HNOI2006 最短母串 狀壓DP

description 給定n個字串 s1,s2,sn 要求找到乙個最短的字串t,使得這n個字串 s1,s2,sn 都是t的子串。sample input 2abcd bcdabc sample output abcdabc 考慮狀壓dp。先去一下重。然後預處理兩個串的最大重疊。然後就是字典序的大小...

旅遊 狀壓 最短路

description db愛好運動,但是單純的運動會使得他很枯燥,現在他想邊跑步邊看風景。已知現在有n個風景點 編號為1號 n號 同時有m條道路將這n個風景點連線起來。這些風景點總共有3類 a,b,c 為了方便表示,我們令 a 0,b 1,c 2。db一開始在1號風景點 可以為a,b,c類 現在d...

習題 國王(狀壓DP)

題目 記憶體限制 64 mib時間限制 500 ms標準輸入輸出 題目型別 傳統評測方式 文字比較 提交提交記錄 返回比賽 題目描述 原題來自 sgu 223 在 n n的棋盤上放k 個國王,國王可攻擊相鄰的 8個格仔,求使它們無法互相攻擊的方案總數。輸入格式 只有一行,包含兩個整數 n 和k 輸出...