zoukankan      html  css  js  c++  java
  • our happy ending(状压dp)

    题意:给定一个n,k,l。

    问有多少长度为n的序列满足选出一些数使得他们相加为k,数列中每个数都在1-l以内。

    Solution

    正解还是很妙的。

    状压dp,设dp[i][j]表示长度为i的序列,能表示出集合为j的序列个数。

    这个状态非常好,我们每局下一个可填的数,可选集合就变成了j|(1<<p-1)|(j<<p&size)

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    ll dp[1<<20],ans;
    int n,k,l,t,ma;
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&k,&l);
            memset(dp,0,sizeof(dp));
            ma=(1<<k)-1;dp[0]=1;
            for(int i=1;i<=n;++i)
              for(int j=ma;j>=0;--j)if(dp[j]){
                 ll pu=dp[j];
                 for(int p=1;p<=min(k,l);++p) {
                    int x=(1<<p-1)|j|((j<<p)&ma);
                    dp[x]+=pu;
                    if(dp[x]>mod)dp[x]-=mod;
                }
                if(l>k){
                    dp[j]+=(pu*(l-k))%mod;
                    if(dp[j]>mod)dp[j]-=mod;
                }
            }ans=0;
            for(int i=1;i<=ma;++i)if(i&(1<<k-1)){ans+=dp[i];if(ans>mod)ans-=mod;}
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    迁移
    zendframework 2 链接数据库
    zendframework 2
    merge sort and quick sort 自己去理解吧
    ubuntu git 使用
    resumablejs 分块上传 断点续传
    video.js html5 视频播放器
    swfupload 例子
    php 润年 星期 天数
    ubuntu 安装 axel
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9682255.html
Copyright © 2011-2022 走看看