码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces245H

时间:2018-11-17 12:03:03      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:hid   i+1   close   bre   std   out   names   lse   题解   

题意如下:给你一个字符串s,给出q次询问,要你求出区间【l,r】中回文子串的数目!

首先的想法是预处理好在一段区间内的的子串是不是回文子串,这可以通过o(n^2)时间内预处理好!

然后接下来是转移方程,我一开始就往n^3的算法去想,发现超市,后来又发现这样无法转移!

后来看了别人的题解才想到递推方程是dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+hw[i][j],为什么要这样转移呢,原理很简单,这样可以避开判断中间的回文串,但是我一直在中间想,没往边界想,哎。还是太年轻啊。。。。。。。。。。。。。。。。。。。。。。。。。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char sz[5100];
 4 int q,len,l,r,n;
 5 int hw[5100][5100];
 6 int dp[5100][5100];
 7 int main(){
 8     scanf("%s",sz+1);
 9     len=strlen(sz+1);
10     n=len;
11     for(int i=1;i<=len;i++){
12         for(int j=1;j<=len;j++){
13             if(i-j<=0||i+j>len) break;
14             if(sz[i-j]==sz[i+j]) hw[i-j][i+j]=1;
15             else break;
16         }
17         for(int j=1;j<=len;j++){
18             if(i-j+1<=0&&i+j>len) break;
19             if(sz[i-j+1]==sz[i+j]) hw[i-j+1][i+j]=1;
20             else break;
21         }
22     }
23     scanf("%d",&q);
24     for(int i=1;i<=n;i++) dp[i][i]=1;
25     for(int i=2;i<=n;i++){
26         for(int j=1;j<=n;j++){
27             if(i+j-1>n) break;
28             int p=i+j-1;
29             dp[j][p]=dp[j][p-1]+dp[j+1][p]-dp[j+1][p-1]+hw[j][p];
30         }
31     }
32     while(q--){
33         scanf("%d%d",&l,&r);
34         cout<<dp[l][r]<<endl;
35     }
36     return 0;
37 }
View Code

 

codeforces245H

标签:hid   i+1   close   bre   std   out   names   lse   题解   

原文地址:https://www.cnblogs.com/pandaking/p/9973118.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!