zoukankan      html  css  js  c++  java
  • hdu

    题意:给出一个长度不超过16的字符串s,问最少删除多少次其中的回文串能把整个s删得干干净净(回文串可跨字母组成),共T组测试数据(T <= 10)。

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628

    ——>>集合上的动态规划。。。和点集配对很像,这里我先求出所有的回文串,然后dp。

    设d[S]表示将集合S中的字母删除需要多少步,结果就是d[(1<<n)-1];

    枚举所有的S,枚举所有S的子集sub;

    状态转移方程:d[S] = min(d[S], d[S^sub)] + 1](如果sub是回文串~这样才算能减一步呀);

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 16 + 1;
    const int INF = 1000000000;
    char s[maxn];
    bool ispal[1<<maxn];
    int d[1<<maxn], n;
    
    void getPal()       //求出所有的回文串
    {
        int S, i, j;
        for(S = 0; S < (1<<n); S++){
            bool ok = 1;
            int m = 0, buf[maxn];
            for(i = 0; i < n; i++) if((1<<i) & S){
                buf[m++] = s[i];
            }
            for(i = 0, j = m-1; i < j; i++, j--){
                if(buf[i] != buf[j]){
                    ok = 0;
                    break;
                }
            }
            ispal[S] = ok;
        }
    }
    
    void dp(){
        int S, sub;
        d[0] = 0;
        for(S = 1; S < (1<<n); S++){
            d[S] = INF;
            for(sub = S; sub > 0; sub = (sub-1) & S){
                if(ispal[sub]) d[S] = min(d[S], d[S^sub] + 1);
            }
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%s", s);
            n = strlen(s);
            getPal();
            dp();
            printf("%d
    ", d[(1<<n)-1]);
        }
        return 0;
    }
    


  • 相关阅读:
    7
    go http请求库HttpRequest
    Golang设计模式
    深挖 go 之 for-range 排坑指南
    go在并发情况下使用map
    Redis知识点总结
    go 条件与循环结构
    数据分析的数据源
    go 生产者消费者模型与发布订阅模型
    go 文件与目录操作
  • 原文地址:https://www.cnblogs.com/aukle/p/3228668.html
Copyright © 2011-2022 走看看