poj1221

来源:互联网 发布:sql求和语句 编辑:程序博客网 时间:2024/05/29 17:27

dp较水题,只要整数划分dp情况了,那么此题就可以瞬间AC了。

大致题意:先给定一个整数串,若该整数串为回文串,且为单峰回文串(即从开头非严格递增到中间,然后从中间非严格递减到结尾),且所有个数的和为n,则为整数n的一个单峰回文串,先要求给出n的值,输出所有整数n的单峰回文串个数。

本题需要注意的是分情况讨论:

1)奇数情况

则减少到1为止

2)偶数情况

则减少到2为止,然后就是整数n/2的划分了,代码中有详细注释。整数划分在上一篇博客中有详细说明,这里不再重叙。

直接看代码: 728K+0MS

#include <stdio.h>#include <stdlib.h>#define Max 300 //预打表250*250的整数划分组合数__int64 dp[Max][Max]; // 记录整数划分组合数__int64 Sum; // 记录最后的个数int n;void Dp(int n,int m){ // 整数划分组合数dpint i,j;for(i=1;i<=n;i++)dp[i][1]=1;for(i=1;i<=m;i++)    dp[1][i]=1;for(i=2;i<=n;i++)for(j=2;j<=m;j++){if(i<=j)dp[i][j]=dp[i][i-1]+1;elsedp[i][j]=dp[i][j-1]+dp[i-j][j];}}int main(){Dp(250,250);  // 预打表while(scanf("%d",&n),n){printf("%d ",n);Sum=1; // 初始化为1,表示数本身的情况if(n&1){ // 若为奇数int inc=1;while(n>1){ // 每次减少2,组合数要加上dp[inc][n],即以减少的数的一半为n,在不超过剩余数的范围内选择数组合成n的不同组合个数,直到剩余数为1为止n-=2;    Sum+=dp[inc][n];//printf("%d %d==%I64d \n",inc,n,dp[inc][n]);inc++;}}else{int temp=n;int inc=1; // 同上原理,只是这里跳出条件为n>2,因为下一次的组合数为dp[n/2][n/2],即原数的一半while(n>2){n-=2;Sum+=dp[inc][n];inc++;}Sum+=dp[temp/2][temp/2];}printf("%I64d\n",Sum); //输出总个数}return 0;}


 

0 0
原创粉丝点击