N-K集合(dp)

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

输入
两个自然数n和k,
输出
计算n-k特殊集合的个数,

思路:就是一个简单的dp
建立状态方程:用dp[i][j] 表示前i 个数 组成的和小于等于n有多少个NK集合
dp[i] [j] = dp[i-1][j] + dp[i-2][j-i]
dp[i-1][j] 不解释
dp[i-2][j-i] 之所以是j-i,是因为和少了i,先减去i

从1…n 求和公式=(n+1)*n /2
所以最后的解 = f[n][k+1…(n+1)*n /2]

#include <bits/stdc++.h>
using namespace std;
long long f[303][10505];
long long tot,n,k;
int main()
{
    scanf("%lld %lld",&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];
    }
    long long ans=0;
    for(int i=k+1;i<=tot;i++)
        ans+=f[n][i];
    printf("%lld",ans);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值