标签:
题目链接:
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; }
HDU3427 Clickomania【记忆化搜索】【区间DP】
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/43667017