题意:
现在给你一个叫Unimodal Palindromic序列的东西,它符合是回文串并且它是峰型的,峰型意味着它就是先递增再递减。
思路:
一开始没思路,后来尝试着找思路,但是打表打出来之后发现有一些问题。因为没有限制条件,于是会发生有重复的现象。于是设dp[i][j]表示当和为i时,而且这个序列中的最小的那个数是大于等于j的时候所能够组成的情况数有几个
于是dp[i][j]=dp[i-j*2][j]+dp[i][j+1]; 这里j相当于是每次取的那个最小的数,比如说1,2,3....到i/2为止。而dp[i][j+1]则是用来进行累加操作的,并且dp[i][j]=1,(i>=j>i/2);这些都预处理成1。同时将dp[i][j]=0,(j>i)。 将dp[0][i]=1,这里是表示一个数完全拆成了两个相等的数,那么结果当然是1个了。
感觉其实就是一道找规律的题嘛~和dp好像没有多大关系。。
#include<cstdio>
#include<cstring>
#include<set>
#include<cmath>
#include<map>
#include<stack>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define maxn 300
ll dp[maxn][maxn];
int main(){
dp[1][1]=1;
for(int i=0;i<251;i++) dp[0][i]=1;
for(int i=2;i<=250;i++){
for(int j=i+1;j<=250;j++) dp[i][j]=0;
for(int j=i/2+1;j<=i;j++) dp[i][j]=1;
for(int j=i/2;j>=1;j--){
dp[i][j]=dp[i-j*2][j]+dp[i][j+1];
}
}
int n;
while(~scanf("%d",&n)){
if(n==0) break;
printf("%d %lld\n",n,dp[n][1]);
}
return 0;
}
/*
2
3
4
5
6
7
8
10
23
24
131
213
92
0
*/