• 《3202: Clickomania》


    这题其实一开始就已经想到了区间dp,但是不是很自信。(网上好像都是写的dfs。)

    首先把连续的一段合并到一起,然后用dp[i][j]来表示i堆~j堆是否能合并。

    主要是合并有很多种合法,一开始少了一种,但是仔细看题目里其实已经提示了你。

    xy型,即最传统的合并。

    xAy型,判断下两头即可。

    AxAyA,一开始就是少了这部分所以没过,我们需要找到一个和首尾相同的来判断。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 1e4+5;
    const LL Mod = 1e9+7;
    #define pi acos(-1)
    #define INF 1e9
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    int dp[205][205],sz[205];
    char a[205];
    int main()
    {
        string s;
        while(cin >> s)
        {
            int tot = 0;
            char pre = 'a';
            memset(dp,0,sizeof(dp));
            for(auto v : s)
            {
                if(v != pre) a[++tot] = v,sz[tot] = 1;
                else sz[tot]++;
                pre = v;
            }
            for(int i = 1;i <= tot;++i) if(sz[i] > 1) dp[i][i] = 1;
            for(int i = 1;i < tot;++i) if(a[i] == a[i + 1] || dp[i][i] && dp[i + 1][i + 1]) dp[i][i + 1] = 1;
            for(int len = 3;len <= tot;++len)
            {
                for(int i = 1;i <= tot;++i)
                {
                    int j = i + len - 1;
                    if(j > tot) break;
                    for(int k = i;k < j;++k) 
                    {
                        if(dp[i][k] && dp[k + 1][j]) dp[i][j] = 1;
                    }
                    for(int k = i + 1;k < j;++k)
                    {
                        int f1 = 0,f2 = 0;
                        if(i + 1 > k - 1 || dp[i + 1][k - 1]) f1 = 1;
                        if(k + 1 > j - 1 || dp[k + 1][j - 1]) f2 = 1; 
                        if(a[i] == a[k] && a[k] == a[j] && f1 && f2) dp[i][j] = 1;//AxAyA
                    }
                    if(a[i] == a[j] && dp[i + 1][j - 1]) dp[i][j] = 1;
                }
            }
            printf("%s
    ",dp[1][tot] ? "solvable" : "unsolvable");
        }
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    System.Web.Security下提供了非常简单的MD5加密算法,但处在非Web层的项目要怎么使用MD5加密呢?
    切换用户账户访问共享 记
    从盛大通行证上摘下来的身份证验证代码
    HA_Xenu1.3.6 使用手记
    asp.net跨域共享session(不能跨主机名)
    应用程序池自动关闭
    忘记 win2003 密码 记
    Ajax 入门 【学习手记】
    转载 防盗链
    超链接的 target
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14108172.html
Copyright © 2020-2023  润新知