• 盒子与小球之三


    描述

    有N个相同的球,M个不同的盒子,每个盒子最多放K个球 
    请计算将这N个球全部放入盒子中的方案数模1000007后的结果 

    输入

    三个正整数,依次为N,M,K

    输出

    输出方案数模1000007后的结果

    样例输入
    4 2 3
    样例输出
    3
    提示

    总共有3种方案,依次为

    { 3 , 1 }

    { 2 , 2 }

    { 1 , 3 }

    对于100%的数据, N,M <= 5000 

    查看

    相比之前的水题,这个题,对我来说就有点难了= =卡时间

    我们可以设计状态F[i][j]表示前i个盒子放j个求有多少种方法,那么F[i][j]=西格玛(F[i-1][j-l]),l的范围是[0,k],状态量是N^2,转移是O(K),复杂度是O(N*M*K),TLE,我们考虑优化转移,我们发现其实l的范围是固定的,类似于一个滑动窗口,那么我们可以维护一个sum,sum=西格玛(F[i-1][j-l]),在j增加后,我们令sum=sum-F[i-1][j-k]+F[i-1][j+1],这样就做到了O(1)转移,时间复杂度O(N*M)[1]

    另外解释一下为什么sum的初始值是m。被注释掉的循环从0到n开始,n的初始值是1,那么和就是ways[m-1][0]+ways[m-1][1]。ways[m-1][0]=1,ways[m-1][1]=m-1

    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<map>
    #include<cstring>
    #define DEBUG(x) cout << #x << " = " << x << endl
    typedef long long ll;
    using namespace std;
    const int MAXN=5e3+10;
    const int MOD=1000007;
    int N,M,K;
    ll ways[MAXN][MAXN];
    ///前m个盒子放入n个球的放法
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d %d %d",&N,&M,&K);
        ways[0][0]=1;
        for(int i=1;i<=M;i++){
            ways[i][0]=1;
            ways[0][i]=0;
        }
        for(int m=1;m<=M;m++){
            int sum=m;
            for(int n=1;n<=N;n++){
    //            int l=min(n,K);
    //            int r=0;
    //            for(int i=0;i<=l;i++){
    //                r=(r+ways[m-1][n-i])%MOD;
    //            }
                ways[m][n]=sum;
                sum=(sum+ways[m-1][n+1])%MOD;
                if(n-K>=0)sum=(sum-ways[m-1][n-K]+MOD)%MOD;
            }
        }
        printf("%lld
    ",ways[M][N]);
        return 0;
    }

    参考文献

    [1]https://blog.csdn.net/TSOI_Vergil/article/details/53102437

  • 相关阅读:
    哈密顿绕行世界问题 (dfs)
    山东省第八届ACM大学生程序设计竞赛
    HDU
    HDU
    hdu 1241(DFS/BFS)
    centos7 df 命令卡死
    hosts文件修改之后立刻刷新
    shell脚本打印日期时间
    CentOS6设置php-fpm开机自启动
    Word中怎么设置忽略拼写和语法检查提醒
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/9180505.html
Copyright © 2020-2023  润新知