0
点赞
收藏
分享

微信扫一扫

HDU3427 Clickomania【记忆化搜索】【区间DP】


题目链接:

​​http://acm.hdu.edu.cn/showproblem.php?pid=3427​​


题目大意:

Clickomania(彩球消除)是一款游戏,有几种颜色不同的方块排成一列。每次可以将一段连续的

颜色相同的方块消除掉,消除后原本这段方块两端的方块连接在一起,比如:ABBBA,将中间

的BBB消除后,就变成了AA。现在给你一段字符串,不同的字符代表不同的颜色,那么问题来

了:能不能将整个字符串消除完。


思路:

字符串的题目。本来感觉题目没有思路、无从下手,所幸题目中给了能够消除的所有情况:xy,

AxA,AxAyA三种情况。x和y表示可以消除的部分。把整个字符串看做一个区间,分解区间为

多个能够消除的子区间,直到不能分解为止。那么,如果还存在无法消除的区间,那么整个字符

串就不能够消除完。如果子区间都能消除掉,那么整个字符串就能消除完。那么,接下来就是具

体实现过程了。

s[]数组来保存字符串,dp[i][j]表示第i个字符到第j个字符是否能被消除,为1则能被消除。用记忆

化搜索的方法判断区间[Left,Right]是否满足xy,AxA,AxAyA三种消除方式,并递归分解解决。


AC代码:


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

char s[160];
int dp[160][160];

bool solve(int Left,int Right)
{
if(Left > Right || dp[Left][Right] == 1)
return true;
if(Left == Right || dp[Left][Right] == -1)
return false;

for(int i = Left+1; i <= Right-2; ++i) //xy型
{
if(solve(Left,i) && solve(i+1,Right))
{
dp[Left][Right] = 1;
return true;
}
}

if(s[Left] == s[Right])
{
if(solve(Left+1,Right-1)) //AxA型
{
dp[Left][Right] = 1;
return true;
}
for(int i = Left+1; i <= Right-1; ++i)
{
if(s[i] == s[Left])
{
if(solve(Left+1,i-1) && solve(i+1,Right-1)) //AxAyA型
{
dp[Left][Right] = 1;
return true;
}
}
}
}
dp[Left][Right] = -1;
return false;
}
int main()
{
while(cin >> s)
{
memset(dp,0,sizeof(dp));
int len = strlen(s);

bool ans = solve(0,len-1);
if(ans)
printf("solvable\n");
else
printf("unsolvable\n");
}

return 0;
}



举报

相关推荐

0 条评论