如有错误,请留言提醒,不要坑到小朋友
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"); }