博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lightoj 1025【区间DP】
阅读量:4984 次
发布时间:2019-06-12

本文共 1289 字,大约阅读时间需要 4 分钟。

题意:

给出一个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
#include
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\n",cas++,ans); } return 0;}

转载于:https://www.cnblogs.com/keyboarder-zsq/p/5934400.html

你可能感兴趣的文章
Docker架构
查看>>
C#设计模式(3)——工厂方法模式
查看>>
过目不忘JS正则表达式
查看>>
bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂
查看>>
Colidity-- StoneWall
查看>>
Leetcode 904. Fruit Into Baskets
查看>>
怎样连接REDIS服务端
查看>>
ajax同步,加载loading的bug
查看>>
秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别
查看>>
div滚动条
查看>>
iOS越狱程序开发
查看>>
一个监听事件监听多个按钮
查看>>
调用其他类的方法
查看>>
SQlite数据库
查看>>
前端开发要注意的浏览器兼容性问题整理
查看>>
Python服务器开发 -- 网络基础
查看>>
开源项目Html Agility Pack实现快速解析Html
查看>>
一些常用的js,jquerry 样例
查看>>
Oracle PL/SQL 多重选择句
查看>>
dorado中的creationType选择类型
查看>>