• 《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
  • 相关阅读:
    移植thinkPHP的dump()函数
    PHP生成linux命令行进度条
    没有ORM库的时候,通过PDO连接MySQL的方法
    mysql json字符串 解析成对应字段
    linux上安装并启动nginx
    linux上启动redis
    mui的input搜索框里的清除按钮的点击监听事件
    miniui 修改input样式及弹出框按钮文字
    js 删除数组元素的方法
    miniui反选
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14108172.html
Copyright © 2020-2023  润新知