您的位置:首页 > 其它

codeforces 835D 区间dp

2017-08-02 17:07 441 查看
简单的区间dp

dp[i][j]表示区间i-j的回文度数

转移方程就是在si=sj且dp[i+1][j−1]>0时dp[i][j]=dp[i+1][(i+j)/2]+1

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
#define LL long long
int dp[5005][5005];
int main()
{
char str[5005];
while(scanf("%s",str)!=EOF)
{
clr(dp);
int len = strlen(str);
int ans[5005] = {0};
for(int i = 0;i<len;i++)
dp[i][i] = 1,ans[1]++;
for(int i = 1;i<len;i++)
{
for(int j = 0;j<len-i;j++)
{
if(i&1) // 偶数个
{
if(i==1)
{
if(str[j]==str[j+i])
{
dp[j][j+i] = 2;
ans[2]++;
}
}
else
{
int l = j+1;
int r = j+i-1;
if(str[j] == str[j+i] && dp[l][r]>0)
{
dp[j][j+i] = dp[j][j+i/2]+1;
ans[dp[j][j+i]]++;
}
}
}
else // 奇数个
{
int l = j+1;
int r = j+i-1;

if(str[j]==str[j+i] && dp[l][r]>0)
{
dp[j][j+i] = dp[j][j+i/2-1]+1;
ans[dp[j][j+i]]++;
}
}
//cout << j << " " << j+i << " num " << dp[j][j+i] << endl;
}
}
//cout << dp[2][4] << endl;
for(int i = len-1;i>=0;i--)
{
ans[i] = ans[i]+ans[i+1];
}
for(int i = 1;i<=len;i++)
{
if(i!=1)printf(" ");
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp codeforces