zoukankan      html  css  js  c++  java
  • CodeForces 245H Queries for Number of Palindromes (区间DP)

    <题目链接>

    题目大意:

    给定字符串$S(|S|<=5000)$,下标由1开始。然后q个问题$(qleq10^6)$,对于每个问题,给定L,R,回答区间[L,R]里有多少个回文串。

    解题分析:

    先预处理出任意区间的字符串是否是回文串,然后就是用区间DP,对每个区间,根据它的子区间的状态进行转移,这里要用到容斥的思想统计一下该区间回文子串的个数。$$dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+pali[i][j]$$

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 5e3+5;
    bool pali[N][N];
    int dp[N][N];
    char str[N];
    
    int main(){
        scanf("%s",str+1);
        int n=strlen(str+1);
        for(int i=1;i<=n;i++)pali[i][i]=1,dp[i][i]=1;
        for(int i=n;i>=1;i--){
            for(int j=i+1;j<=n;j++){
                if(str[i]==str[j] && j-i==1)pali[i][j]=1;   //特判一下长度为2的区间
                else if(str[i]==str[j] && pali[i+1][j-1])pali[i][j]=1;
            }
        }//先用简单的区间DP,预处理出所有区间的子串是否是回文串
        for(int i=n;i>=1;i--){
            for(int j=i+1;j<=n;j++){
                dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+pali[i][j];   //用容斥进行该区间内回文子串数量的统计
            }
        }
        int q;scanf("%d",&q);
        while(q--){
            int l,r;scanf("%d%d",&l,&r);
            printf("%d
    ",dp[l][r]);
        }
    }
  • 相关阅读:
    两数之和
    数组,链表,跳表
    第二讲:增长全景图
    三数之和
    第一讲:增长的本质
    移动零
    八十忆双亲+师友杂记
    java:从命令行接收多个数字,求和之后输出结果
    编程的精义读后感
    java语言基础第三讲作业
  • 原文地址:https://www.cnblogs.com/00isok/p/10651550.html
Copyright © 2011-2022 走看看