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;
}
时间: 2024-11-04 21:32:22

HDU3427 Clickomania【记忆化搜索】【区间DP】的相关文章

hdu 4597 Play Game (记忆化搜索 区间dp)

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int dp[30][30][30][30]; int vis[30][30][30][30]; int a[2][30],sum[2][30]; int dfs(int i,int j,int k,int l) { if(vi

hdu3555 Bomb (记忆化搜索 数位DP)

http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7316    Accepted Submission(s): 2551 Problem Description The counter-terrorists found a time

poj 3156 hash+记忆化搜索 期望dp

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; #define N 32 #define mod 10007LL #define mod2 10000007 #define inf 0x3fffffff typedef long long ll; typedef double dd; int f[N]

记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty

题目传送门 1 /* 2 题意:给了两堆牌,每次从首部取出一张牌,按颜色分配到两个新堆,分配过程两新堆的总数差不大于1 3 记忆化搜索(DFS+DP):我们思考如果我们将连续的两个操作看成一个集体操作,那么这个操作必然是1红1黑 4 考虑三种情况:a[]连续两个颜色相同,输出11:b[]连续两个相同,输出22: 5 a[x] != b[y], 输出12:否则Impossible 6 详细解释:http://blog.csdn.net/jsun_moon/article/details/10254

HDU 2476 String painter(记忆化搜索, DP)

题目大意: 给你两个串,有一个操作! 操作时可以把某个区间(L,R) 之间的所有字符变成同一个字符.现在给你两个串A,B要求最少的步骤把A串变成B串. 题目分析: 区间DP, 假如我们直接想把A变成B,那么我们DP区间的时候容易产生一个问题:假如我这个区间更新了,那么之前这个区间的子区间内DP出来的值就没用. 然后考虑到这里一直想不过去.最后看了看题解才知道. 我们可以先预处理一下怎么将一个空串变成B串需要的操作数. 这样我们就不用考虑子区间被覆盖的情况了. 如区间L,R 我们需要考虑的是点L是

硬币找零-记忆化搜索(DP动态规划)

硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该注意到,人民币的硬币系统是 100,50,20,10,5,2,1,0.5,0.2,0.1,0.05, 0.02,0.01 元,采用这些硬币我们可以对任何一个工资数用贪心算法求出其最少硬币数. 但不幸的是: 我们可能没有这样一种好的硬币系统, 因此

UVA 10626--Buying Coke+记忆化搜索+DP

题目链接:点击进入 原来定义状态dp[n][n1][n5][n10]表示购买n瓶可乐后剩余1,5,10分硬币n1,n5,n10个时花费硬币数最小的数量.然后状态转移是:1.8个一分硬币购买第n瓶可乐,t=dp[n-1][n1+8][n5][n10]+8; 2.一个五分和3个1分,t=dp[n-1][n1+3][n5+1][n10]+4; 3.两个5分t=dp[n-1][n1][n5+2][n10]; 4.一个10分,t=dp[n-1][n5][n10+1]. 对于第一二种dp[n][n1][n5

Codeforces Round #338 (Div. 2) B. Longtail Hedgehog 记忆化搜索/树DP

B. Longtail Hedgehog This Christmas Santa gave Masha a magic picture and a pencil. The picture consists of n points connected by m segments (they might cross in any way, that doesn't matter). No two segments connect the same pair of points, and no se

UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?

题目链接: 题目链接 题意:如果一个数二进制n有k位1,那么f1[n] = k,如果k有s位二进制1,那么f2[n] = f1[k] = s.  如此往复,直到fx[n] = 1,此时的x就是n的”K值“,现在要求[L,R]内的”K值“为X的数有多少个.(1<=L<=R<=10^18) 解法:首先可以看到10^18最多只有61位左右的数,所以我们只需处理1~61之间每个数有多少个1,即可知道1~61之间每个数”K值“是多少. 然后就将求[L,R]之间的个数变成求[1,R]-[1,L-1]

矩形嵌套-记忆化搜索(dp动态规划)

矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 有n个矩形,每个矩形能够用a,b来描写叙述,表示长和宽. 矩形X(a,b)能够嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).比如(1,5)能够嵌套在(6,2)内,但不能嵌套在(3,4)中. 你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每个矩形都能够嵌套在下一个矩形内. 输入 第一行是一个正正数N(0<N<10).表示測试数据组