HDU 4632 Palindrome subsequence & FJUT3681 回文子序列种类数(回文子序列个数/回文子序列种数 容斥 + 区间DP)题解
题意1:问你一个串有几个不连续子序列(相同字母不同位置视为两个)
题意2:问你一个串有几种不连续子序列(相同字母不同位置视为一个,空串视为一个子序列)
思路1:由容斥可知当两个边界字母相同时 dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1;当两个字母不同时 dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1]。然后区间DP即可
思路2:由思路1我们能大致知道怎么做,显然两边界字母不一样时情况是一样的。当两边字母一样时,那么就要判断中间的重复情况。
我们设l和r,表示i + 1 ~ j - 1里最左边的s[i]字母和最右边的s[i]字母
当 l == r 那么就只有一个相同字母,dp[i][j] = dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1,答案为中间部分 + 中间加上两边界 + s[i]s[j]串
当 l > r,没有这个字母,dp[i][j] = dp[i + 1][j - 1] + dp[i + 1][j - 1] + 2,答案为中间部分 + 中间加上两边界 + s[i]s[j]串 + s[i]
当l < r,说明至少有两个字母,dp[i][j] = dp[i + 1][j - 1] + dp[i + 1][j - 1] - dp[l + 1][r - 1],答案为中间部分 + 中间加上两边界 - (l,r)区间内种数,因为这里面的和s[l],s[r]组成的串和s[i],s[j]重复
代码1:
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1e3 + ;
const ll MOD = 1e4 + ;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxn]; //i到j种数
char s[maxn];
int main(){
int t, ca = ;
scanf("%d", &t);
while(t--){
scanf("%s", s + );
int n = strlen(s + );
for(int i = ; i <= n; i++){
dp[i][i] = ;
}
for(int len = ; len <= n; len++){
for(int i = ; i + len - <= n; i++){
int j = i + len - ;
if(s[i] == s[j]){
dp[i][j] = dp[i + ][j] + dp[i][j - ] + ;
}
else{
dp[i][j] = dp[i + ][j] + dp[i][j - ] - dp[i + ][j - ];
}
dp[i][j] = (dp[i][j] + MOD) % MOD;
}
}
printf("Case %d: %d\n", ca++, dp[][n]);
}
return ;
}
代码2:
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1e3 + ;
const ll MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
ll dp[maxn][maxn]; //i到j种数
char s[maxn];
int main(){
int t, ca = , n;
scanf("%d", &t);
while(t--){
scanf("%s", s + );
int n = strlen(s + );
for(int i = ; i <= n; i++){
dp[i][i] = ;
}
for(int len = ; len <= n; len++){
for(int i = ; i + len - <= n; i++){
int j = i + len - ;
if(s[i] == s[j]){
int l = i + , r = j - ;
while(s[l] != s[i] && l <= r) l++;
while(s[r] != s[i] && l <= r) r--;
if(l > r){
dp[i][j] = dp[i + ][j - ] + dp[i + ][j - ] + ;
}
else if(l == r){
dp[i][j] = dp[i + ][j - ] + dp[i + ][j - ] + ;
}
else{
dp[i][j] = dp[i + ][j - ] + dp[i + ][j - ] - dp[l + ][r - ];
}
}
else{
dp[i][j] = dp[i + ][j] + dp[i][j - ] - dp[i + ][j - ];
}
}
}
printf("Case %d: %lld\n", ca++, dp[][n]);
}
return ;
}
HDU 4632 Palindrome subsequence & FJUT3681 回文子序列种类数(回文子序列个数/回文子序列种数 容斥 + 区间DP)题解的更多相关文章
- HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)
题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. ...
- HDU 4632 Palindrome subsequence (区间DP)
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- HDU 4632 Palindrome subsequence (区间DP)
题意 给定一个字符串,问有多少个回文子串(两个子串可以一样). 思路 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字符串中[i,j]位置中出现的回文子序 ...
- HDU 4632 Palindrome subsequence (2013多校4 1001 DP)
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- HDU 4632 Palindrome subsequence(区间dp)
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- HDU 4632 Palindrome subsequence(区间DP求回文子序列数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632 题目大意:给你若干个字符串,回答每个字符串有多少个回文子序列(可以不连续的子串).解题思路: 设 ...
- hdu 4632 Palindrome subsequence
http://acm.hdu.edu.cn/showproblem.php?pid=4632 简单DP 代码: #include<iostream> #include<cstdio& ...
- HDU 4632 Palindrome subsequence(DP)
题目链接 做的我很无奈,当时思路很乱,慌乱之中,起了一个想法,可以做,但是需要优化.尼玛,思路跑偏了,自己挖个坑,封榜之后,才从坑里出来,过的队那么多,开始的时候过的那么快,应该就不是用这种扯淡方法做 ...
- 【HDU】4632 Palindrome subsequence(回文子串的个数)
思路:设dp[i][j] 为i到j内回文子串的个数.先枚举所有字符串区间.再依据容斥原理. 那么状态转移方程为 dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+ ...
随机推荐
- c#关于字符串格式化
1. 如何使用文化来格式化日期 如: /// <summary> /// 根据语言获取文化名称 /// </summary> /// <returns></r ...
- <<Natural Language Inference over Interaction Space >> 句子匹配
模型结构 code :https://github.com/YichenGong/Densely-Interactive-Inference-Network 首先是模型图: Embedding Lay ...
- 《大话设计模式》c++实现 工厂模式
工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客户端 ...
- 【Elasticsearch学习之一】Elasticsearch
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 一.概念ElasticSearch: 基于Lucene全文搜 ...
- Linux Firewall 开启与关闭 以及sudo 设置
Linux 系统下,普通用户经常需要使用root 用户的权限,所以要经常切换到root用户,比较麻烦,因此可以给普通用户添加root 权限,需要在常规命令前面加上sudo 切换到root vi /e ...
- 安卓apk的编译与反编译
原文:https://blog.csdn.net/baidu_33870664/article/details/80186945 android基于java的,而java反编译工具很强悍,所以对正常a ...
- impala与hive的比较以及impala的有缺点
最近读的几篇关于impala的文章,这篇良心不错:https://www.biaodianfu.com/impala.html(本文截取部分内容) Impala是Cloudera公司主导开发的新型查询 ...
- python中的作用域以及内置函数globals()-全局变量、locals()-局部变量
在python中,函数会创建一个自己的作用域,也称为为命名空间.这意味着在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 通过内置函数globals()返回的是python解释器能知道的变 ...
- JS中对象与数组(大括号{}与中括号[])
一.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数. 如:var LangShen = {"Name":"Langshen",&qu ...
- [转载]dbms_lob用法小结
http://blog.sina.com.cn/s/blog_713978a50100prkt.html CLOB里存的是2进制 判定长度 DBMS_LOB.GETLENGTH(col1)获取文本 ...