zoukankan      html  css  js  c++  java
  • lightoj 1025【区间DP】

    题意:
    给出一个word,求有多少种方法你从这个word清除一些字符而达到一个回文串。

    思路:
    区间问题,还是区间DP;
    我判断小的区间有多少,然后往外扩大一点。
    dp[i,j]就代表从i到j的方案数。

    状态转移:

    其实对于在任意区间[i ,j],都可以,
    在子区间[i+1,j]中可以直接去掉s[j]时,顺便去掉s[i],所以就有它的方案,
    在子区间[i,j-1]中可以直接去掉s[i]时,顺便去掉s[j],所以就有它的方案,
    但是s[i],s[j]不相等的时候
    dp[i+1,j],dp[i,j-1]会重复一个情况(把s[i]和s[j]都删除了)
    所以再减去一个dp[i+1,j-1]就好了;
    相等的话,虽然可以直接把两端去掉,但是我们可以把多出来的这一部分首尾加上s[i]和s[j],
    这样就又是不同的情况了,所以不需要再减去。
    然后还有一种特殊的情况就是把区间[i+1, j-1]全部删完,只留一个s[i]和s[j]
    膜泰巨blog【点这里~

    #include<bits/stdc++.h>
    #include<string.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const double eps=1e-5;
    const double pi=acos(-1.0);
    const int mod=1e8+7;
    const LL INF=0x3f3f3f3f;
    
    const int N=66;
    char s[N];
    
    LL solve()
    {
        LL dp[N][N];
        int len=strlen(s+1);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=len;i++)
        {
            for(int j=1;(j+i-1)<=len;j++)
            {
                int k=j+i-1;
    
                dp[j][k]=dp[j+1][k]+dp[j][k-1];
                if(s[j]==s[k])
                    dp[j][k]+=1;
                else
                    dp[j][k]-=dp[j+1][k-1];
            }
        }
        return dp[1][len];
    }
    int main()
    {
        int cas=1;
        int t;
        scanf("%d",&t);
        while(t--)
        {
            LL ans;
            scanf("%s",s+1);
            ans=solve();
            printf("Case %d: %lld
    ",cas++,ans);
        }
        return 0;
    }
  • 相关阅读:
    兼容性处理
    H5 IOS 虚拟键盘不回落的问题
    git 的版本控制
    vue-devtools工具的安装
    linux下安装mysql
    Python安装pip3常见问题
    linux下安装python3
    接口_注册接口
    接口_简单get接口_第一个接口
    Python学习笔记_Redis
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934400.html
Copyright © 2011-2022 走看看