HDU-4602 partition 找规律

45 篇文章 0 订阅

分析:

看了解题报告,先没看懂,后来恍然大悟。

当k>n 显然是不存在的答案为0;

当1<=k=n时,有个很好的技巧,把n拆分n个1,(n=1+1+1.......1),那么对于整数k,相当于连续取k个1,其它可以任意分开。

分两种情况讨论, 取k个连续的点不包含端点。在n个位置区k个连续的点有n-1-k种,在就是把剩余的n-k-2位置任意分割,相当于n-k-2任意拆分,根据题意提供f(n)=2^n。

很快就得到(n-k-1)*2^(n-k-2);

如果含有端点,最前和最后,有2种,那么就有2*2^(n-k-1)

加起来就是:(n-k+3)*2^(n-k-2);

代码:

#include<stdio.h>
#define mod 1000000007
typedef __int64 LL;
int main()
{
	int t;
	LL sum,ret,k,n;
	scanf("%d",&t);
	while(t--){
		scanf("%I64d %I64d",&n,&k);
		if(k>n) puts("0");
		else if(k==n) puts("1");
        ret=n-k+3;
        k=n-k-2;
        sum=2;
        if(k==-1) printf("%I64d\n",ret>>1);
		if(k>=0) {
			while(k){
				if(k&1)
				   ret=(ret*sum)%mod;
				sum=(sum*sum)%mod;
				k>>=1;
			}
			printf("%I64d\n",ret);
		}	
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值