給定n個字串(s1,s2,„,sn),要求找到乙個最短的字串t,使得這n個字串(s1,s2,„,sn)都是t的子串。
第一行是乙個正整數n(n<=12),表示給定的字串的個數。
以下的n行,每行有乙個全由大寫字母組成的字串。每個字串的長度不超過50.
只有一行,為找到的最短的字串t。在保證最短的前提下,
如果有多個字串都滿足要求,那麼必須輸出按字典序排列的第乙個。
2 abcd
bcdabc
abcdabc
我對著乙個不滿足最優子結構的dp調了1個多小時,重點是竟然騙了80分哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。
#include #include乙個瞎yy的奇形怪狀的dp#include
#include
using
namespace
std;
#define reg register
intn;
string str[15
];int len[15
];int bin[14
];string f[13][1
<<12
];string
ans;
intmain()
//// if (i == 1 and j == 2) system("pause");
//if (comb[i][j] == "") comb[i][j] = str[i] + str[j];//}
//}for (reg int s = 1 ; s <= bin[n] - 1 ; s ++)
if (!find) comb =str[j];
if (f[j][s | bin[j - 1]] == "" or f[j][s | bin[j - 1]] > f[i][s] + comb) f[j][s | bin[j - 1]] = f[i][s] +comb;}}
}//cout/
cout/
cout << (f[4][bin[n]-1] < f[2][bin[n]-1]) << endl;
ans = f[1][bin[n] - 1
];
for (reg int i = 2 ; i <= n ; i ++)
cout
<< ans <
return0;
}
其實正解是ac自動機加狀壓dp。
然後不知道為什麼寫萎了還只有80分,剩下的都re了,不管了不想調了。
#include #include#include
#include
#include
using
namespace
std;
#define reg register
intn;
char str[15][550
];int bin[14
];string
ans;
char ch[6005
];int nxt[6005][27
], tot;
int sit[6005], fail[6005
];inline
void insert(char *s, int
id) sit[now] |= bin[id - 1];}
inline
void
ac_match()
}}struct
node ;
bool vis[605][1
<<12
];int pre[60005], top, road[60005
];inline
void print(int
x)inline
void
bfs()
); vis[
0][sit[0]] = 1
;
while(!q.empty())
for (reg int i = 0 ; i < 26 ; i ++));}
}}int
main()
BZOJ 1195 HNOI2006 最短母串
一看字串就想到ac自動機是不是沒救了 然後決定在ac自動機上做分層圖最短路233333333 結果發現極限資料剛好卡時限了qaq 仔細一想好像每條邊的長度都是1哎。果斷bfs 其實dfs應該也可以的吧,而且可以剪枝。但是我有dfs恐懼症,於是果斷選擇了bfs。結果跑得奇慢無比。不談了我想靜靜 inc...
bzoj1195 HNOI2006 最短母串
此題似乎是乙個dp。dp i j 表示選了i這個集合的字串,最後乙個是j的最短字串。字典序順便搞定 然後發現需要處理掉一串為另一串子串的情況,特判一些特殊情況 或者奇怪的姿勢 就好了。這題很卡空間,請務必不要亂開陣列。include define gc getchar using namespace...
BZOJ 1195 HNOI2006 最短母串
time limit 10 sec memory limit 32 mb submit 1346 solved 450 submit status discuss 給定n個字串 s1,s2,sn 要求找到乙個最短的字串t,使得這n個字串 s1,s2,sn 都是t的子串。第一行是乙個正整數n n 12...