codeforces H. Queries for Number of Palindromes(区间dp)
2024-10-21 04:27:42
题目链接:http://codeforces.com/contest/245/problem/H
题意:给出一个字符串还有q个查询,输出每次查询区间内回文串的个数。例如aba->(aba,a,b,a)有4个
题解:如果遇到区间而且数又不大n*n能存下来的可以考虑一下用区间dp,然后区间dp一般都是可以通过
预处理来减少for的层数,这里可以预处理一下Is[i][j]表示i,j区间是否是回文串然后dp转移方程就显而易见了。
dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+Is[i][j];
#include <iostream>
#include <cstring>
using namespace std;
const int M = 5e3 + 10;
char s[M];
bool Is[M][M];
int dp[M][M];
int main() {
int q;
scanf("%s" , s);
int len = strlen(s);
memset(Is , false , sizeof(Is));
for(int i = 0 ; i < len ; i++) {
Is[i][i] = true;
}
for(int l = 1 ; l < len ; l++) {
for(int i = 0 ; i < len && i + l < len ; i++) {
int j = i + l;
if(s[i] == s[j]) {
if(l == 1) {
Is[i][j] = true;
}
else {
if(Is[i + 1][j - 1]) {
Is[i][j] = true;
}
}
}
}
}
memset(dp , 0 , sizeof(dp));
for(int i = 0 ; i < len ; i++) {
dp[i][i] = 1;
}
for(int l = 1 ; l < len ; l++) {
for(int i = 0 ; i < len && i + l < len ; i++) {
int j = i + l;
if(l == 1) {
dp[i][j] = dp[i][i] + dp[j][j] + Is[i][j];
}
else {
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + Is[i][j];
}
}
}
scanf("%d" , &q);
while(q--) {
int l , r;
scanf("%d%d" , &l , &r);
printf("%d\n" , dp[l - 1][r - 1]);
}
return 0;
}
最新文章
- 大叔也说Xamarin~Android篇~日志的记录
- distribution数据库过大问题
- Jenkins进阶系列之——11修改Jenkins用户的密码
- Ul li 竖排 菜单
- Android SDK生成时,自定义文件名称,而非系统第一分配的app-release.apk
- jquery trigger伪造a标签的click事件取代window.open方法
- C# SerializableDictionary序列化/反序列化
- Linux 内核使用的 GNU C 扩展
- linux(fedora) 下dvwa 建筑环境
- 编译GDAL支持OpenCL使用GPU加速
- Python笔记-IO编程
- iTOP-4418开发板支持Android4.4/5.1.1系统、Linux3.4.39、QT2.2/4.7/5.7、Ubuntu12.04
- 【XSY2716】营养餐 博弈论
- phpExcel导入大数据量情况下内存溢出解决方案
- JAVA中解决Filter过滤掉css,js,图片文件等问题
- GDI+_SavePic
- PHP工厂模式的使用场景,使用方法
- pta_l1-6(连续因子)
- LeetCode133:Clone Graph
- 《Effective Java》读书笔记(二)之对于所有对象都通用的方法