hdu 5311 Hidden String dp o(n)算法 深搜
2015-07-27 11:26
417 查看
Hidden String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 857 Accepted Submission(s): 322
[align=left]Problem Description[/align]
Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets a string
s
of length n.
He wants to find three nonoverlapping substrings s[l1..r1],
s[l2..r2],
s[l3..r3]
that:
1. 1≤l1≤r1<l2≤r2<l3≤r3≤n
2. The concatenation of s[l1..r1],
s[l2..r2],
s[l3..r3]
is "anniversary".
[align=left]Input[/align]
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤100),
indicating the number of test cases. For each test case:
There's a line containing a string s
(1≤|s|≤100)
consisting of lowercase English letters.
[align=left]Output[/align]
For each test case, output "YES" (without the quotes) if Soda can find such thress substrings, otherwise output "NO" (without the quotes).
[align=left]Sample Input[/align]
2
annivddfdersewwefary
nniversarya
题意,就是给一段字符串,要求找出目标串,且最多只能三个片段串。
由于s很小,所以用深搜,暴力乱搞就好了。但这里用dp也能解决。复杂度是o(n)
定义pre[i][j] 表示字符串第i个位置,从目标串往后能匹配pre[i][j] 个,也就是说s(i,i+pre[i][j] ) == g(j,j+pre[i][j] ) g表示目标串。
则pre[i][j] 转状转移很简单就是pre[i+1][j+1]转移来就可以了。
定义dp[i][j]表示,字符串第i-1个位置前已经匹配到了目标串g的第j-1个位置且已用的分段数就是dp[i][j]。则状态转移方程就是
dp[i][j]可以从dp[i-1][j]得来,也可以转移到dp[i+pre[i][j]][j+pre[i][j]],取分段数的最小值。
答案只要dp[s][11]大于1,说明存在。
由于本题目标串g的长度为定值,所以复杂度为o(s * 11)线性算法,如果,改变一下,g不是字长,而是变长的,那么复杂度则为o(s* g)了,与分段数是无关的。
#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,glen,len,dp
[12],pre
[11];
char str
;
char goal[20] = "anniversary";
void Update(int & a,int b){
if(a == 0) a = b;
else a = min(a,b);
}
int main()
{
glen = strlen(goal);
while(S(n)!=EOF)
{
while(n--){
SS(str);len = strlen(str);
FI(len){
FJ(11){
if(str[i] == goal[j]) pre[i][j] = 1;
else pre[i][j] = 0;
}
}
for(int i = len - 2;i>=0;i--){
FJ(10){
if(pre[i][j] && pre[i+1][j+1]) pre[i][j] = pre[i+1][j+1] + 1;
}
}
fill(dp,0);
for(int i = 0;i<len;i++){
FJ(11){
if(i && dp[i-1][j]) Update(dp[i][j],dp[i-1][j]);
if((dp[i][j] || !j )&&dp[i][j] < 3 && pre[i][j]){
Update(dp[i+pre[i][j]][j+pre[i][j]],dp[i][j] + 1);
}
}
}
bool flag = true;
for(int i = 0;i<=len && flag;i++){
if(dp[i][11]) flag = false;
}
if(!flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
再给个用深搜暴力解决的,更简单,更好理解,也好写,在比赛的时候,抢时间,也能有用处,但复杂度就很高了。
#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,glen,len;
char str
;
char goal[20] = "anniversary";
bool DFS(int si,int gi,int num){
if(num <=3 && gi >= glen) return true;
if(num > 3) return false;
for(int i = si;i<len;i++){
int ti = i,tgi = gi;
while(ti<len && tgi < glen && str[ti] == goal[tgi]) tgi++,ti++;
if(ti > i && DFS(ti,tgi,num + 1)) return true;
}
return false;
}
int main()
{
glen = strlen(goal);
while(S(n)!=EOF)
{
while(n--){
SS(str);len = strlen(str);
if(DFS(0,0,0))
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
[align=left]Sample Output[/align]
YES
NO
[align=left]Source[/align]
BestCoder 1st Anniversary ($)
[align=left]Recommend[/align]
hujie | We have carefully selected several similar problems for you: 5315 5314 5312 5310 5309
相关文章推荐
- 《实体解析与信息质量》 - 3.1.2 SERF模型
- 南阳oj 语言入门 A+B paoblem 题目477 题目844
- 高仿qq‘一键下班’—让你的view‘黏’起来
- 极客班GeekBand - 互联网思维修炼 - 1
- 配置核查模块 开发总结 (1)
- Android Dev Tool 国内网站
- 极客编程小挑战#27:生成动态大眼睛的效果
- HDOJ 题目分类
- Python开发入门与实战12-业务逻辑层
- 防止按钮在短时间被连续点击
- NYOJ 79 拦截导弹(dp)
- 卡片动画初体验
- Namp新增脚本 tor-consensus-checker
- 加载本地Html文件
- HDU 1066敌兵布阵
- 在javaScript中关于submit和button的区别介绍
- ZOJ 2770--Burn the Linked Camp 【差分约束】
- windows下bat批处理文件语法
- Hadoop2.2.0--Hadoop Federation、Automatic HA、Yarn完全分布式集群结构
- collections——高性能容器数据类型