虽说是什么单峰回文串,其实就是整数的划分。
通过题目例子不难看出,分为奇数和偶数,奇数相对简单一点,但偶数也不是很复杂。
至于整数划分的知识,这里不细讲了,我在算法总结里面讲的很详细了。
这是链接:http://blog.csdn.net/u013983192/article/details/28428107
相信看完整数划分的部分,你一定对这道题有思路啦。
如果n是奇数:
f=2+sigma( dp[(n-2*i-1)/2][2*i+1] ) (1<=i<=n/2) (特例,n==1,f=1;)
如果n为偶数:
f=1+sigma( dp[(n-2*i)/2][2*i] ) (1<=i<=n/2)
f+=dp[n/2][n/2];
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 2222
using namespace std;
__int64 dp[MAX][MAX];
__int64 f;
int n;
void init() //离线计算整数划分方案数
{
int i,j;
for(i=1;i<MAX;i++)
{dp[1][i]=1;dp[i][1]=1;}
for(i=2;i<MAX;i++)
{
for(j=2;j<MAX;j++)
{
if(i==j) {dp[i][j]=dp[i][j-1]+1;continue;}
if(j>i) {dp[i][j]=dp[i][i];continue;}
dp[i][j]=dp[i-j][j]+dp[i][j-1];
}
}
}
int main()
{
int i,j;
init();
scanf("%d",&n);
while(n)
{
if(n%2) //n为奇数
{
f=2;
for(i=1;i<=n/2;i++)
{
f+=dp[(n-2*i)/2][2*i+1];
}
if(n==1) f--;
}
else //n为偶数
{
f=1;
for(i=1;i<=n/2;i++)
{
f+=dp[(n-2*i)/2][2*i];
}
f+=dp[n/2][n/2];
}
printf("%d %I64d\n",n,f);
scanf("%d",&n);
}
return 0;
}