您的位置:首页 > 其它

统计n-k特殊集的数目

2014-07-27 22:14 113 查看
【题目】如果正整数构成的集合X满足以下条件,我们称它为n-k特殊集:

1、集合X中的每个元素x均不超过n,即1<=x<=n.

2、集合X中所有的元素之和大于k.

3、集合X中不包含任意一对相邻的自然数.

给出n,k,求n-k特殊集合有多少个。1<=n<=100 ,0<=k<=400.

样例输入:6 3

样例输出:17

样例输入:14 55

样例输出:1

样例输入:40 1000

样例输出:367185615

【分析】设n-k特殊集的个数为f(n,k),我们要想办法来建立它的递推式。由于几何中的元素不能重复,元素n要么要集合中恰好出现一次,要么不出现,二者不重复、不遗漏地把n-k特殊集分成两部分:

1、n不出现。则f(n,k) = f(n-1,k).

2、n出现一次。则f(n,k) = f(n-2,k-n).

所以递推表达式为:f(n,k) = f(n-1,k) + f(n-2,k-n).

边界条件是什么呢?(这儿我也有点不懂)

当n<=0,k>=0时,f(0,k) = 0.

当n<=0,k<0时,f(0,k) = 1.

由上式可看出:k<0是,f(n,k)与k无关,用 -1 来代表所有的负数,这样可得到下式:

f(n,k) = 0(n = 0,-1,k>=0)

f(n,-1) = 1(n = 0,-1)

为了符合平时的书写习惯 ,我们用宏来处理负数的数组下标。

代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
#define F(i,j) (f[(i)+1][(j)+1])    //宏处理

long long f[200][500];
int main()
{
   int i,j,k,n;
   while(cin>>n>>k){
    for(j = -1; j <= k; j++)
        F(-1,j) = F(0,j) = 0;
    F(-1,-1) = F(0,-1) = 1;
    for(i = 1; i <= n; i++)
    for(j = -1; j <=k; j++){
        F(i,j) = F(i-1,j);
        if(j-i < 0)
            F(i,j) += F(i-2,-1);
        else
            F(i ,j) += F(i-2,j-i);
    }
    cout<<F(n,k)<<endl;
   }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐