前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【HDU 4602】Partition

【HDU 4602】Partition

作者头像
饶文津
发布2020-06-02 14:40:28
2460
发布2020-06-02 14:40:28
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

给你一个数n,把它写成几个正整数相加的形式,即把n拆开成若干段,把所有可能的式子里正整数 k 出现的次数取模是多少。

分析

特判 k>=n 的情况。

k<n时:问题相当于n个点排一行,选其中连续的k个点,其他点的间隔情况有多少种。

n个点原来有n-1个两两之间的间隔,当n-k>1时,如果k个点不包含端点,那么剩下的间隔就是:n-1 -(k+1)=n-k-2。此时每个间隔,就有隔或者不隔2种情况,选这k个点的方法又有n-k-1种,所以共有2的n-k-2次方 * (n-k-1)种间隔方案。

如果包含端点,剩下的间隔就是:n-1 -k。因为两个端点,所以有2*(2的n-1-k次方)种间隔方案。

所以总共有2n-k-2*(n-1-k)+2*2n-1-k=(n-3-k)*2n-k-2种方案。

注意到如果n-k=1,那么只有包含端点的情况,答案就是2,故也进行特判。

然后用快速幂取模就可以啦。

代码

代码语言:javascript
复制
#include<cstdio>
#define ll long long
ll m=1e9+7;
ll qpow(int b)
{
    ll a=2,ans=1;
    while(b)
    {
        if(b&1)ans=ans*a%m;
        a=a*a%m;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll t,n,k;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&k);
        if(n<k)
            printf("0\n");
        else if(n==k)
            printf("1\n");
        else if(n-k==1)
            printf("2\n");
        else
            printf("%lld\n",(n-k+3)*qpow(n-k-2)%m);
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-02-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档