N-K集合(dp)

如有错误,请留言提醒,不要坑到小朋友

Description

我们说一个由自然数构成的集合X是n-k特殊集合,则它满足 
1 对于集合X中的每个元素x,有1<=x<=n, 
2 集合X中所有元素的和大于k, 
3 集合X中不包含任意一对相邻的自然数。 

任务 
● 读入两个自然数n和k, 
● 计算n-k特殊集合的个数, 


Input

第一行是两个自然数n和k,中间由一个空格隔开。 
1<=n<=100,0<=k<=400。 

Output

只有一个非负整数,代表了n-k集合的个数。 

Sample Input

5 6



Sample Output

3
用f[i][j]代表前i个数可以组成和小于等于j有多少个n-k集合
那么转移f[i][j]=f[i-2][j-i]+f[i-1][j];
最后答案就是f[n][k..(n+1)*n/2];
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<climits>
#define min(a,b) ((a)>(b)?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
long long f[302][10502],tot;
long long  n,k;
int main(){
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	scanf("%I64d%I64d",&n,&k);
	tot=(long long)(1+n)*n/2;
	f[0][0]=1;f[1][1]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=tot;j++){
			f[i][j]+=f[i-1][j];
			if(i>=2&&j-i>=0)
			f[i][j]+=f[i-2][j-i];//f[i-2][j-i];
		//	printf("f[%d][%d]=%d\n",i,j,f[i][j]);
		}
	long long ans=0;
	for(int i=k+1;i<=tot;i++)ans+=f[n][i];
	printf("%I64d\n",ans);	
//	system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值