poj1221

11 篇文章 0 订阅

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){ // 整数划分组合数dp
	int 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;
			else
				dp[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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值