• 【BZOJ】【3398】【USACO 2009 Feb】Bullcow 牡牛和牝牛


    组合计数/乘法逆元

      排列组合求总方案数

      这个可以用一个一维的动态规划解决:

        f[i][0]表示第i头牛是牝牛的方案数

        f[i][1]表示第i头牛是牡牛的方案数

        则转移为:f[i][0]=f[i-1][0]+f[i-1][1];

                f[i][1]=f[i-K-1][0]+f[i-K-1][1];

    常数优化:将取模运算改为if判断语句……可从20ms降为16ms

     1 /**************************************************************
     2     Problem: 3398
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:16 ms
     7     Memory:1588 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 3398
    11 #include<cstdio>
    12 #define F(i,j,n) for(int i=j;i<=n;++i)
    13 int getint(){
    14     int v=0,sign=1; char ch=getchar();
    15     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
    16     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
    17     return v*=sign;
    18 }
    19 const int N=100086,P=5000011;
    20 int f[N][2],n,K;
    21 int main(){
    22     n=getint(); K=getint();
    23     f[1][0]=f[1][1]=1;
    24     F(i,2,n){
    25         if(i-K-1>0) f[i][1]=f[i-K-1][0]+f[i-K-1][1];
    26         else f[i][1]=1;
    27         f[i][0]=f[i-1][0]+f[i-1][1];
    28         if(f[i][0]>=P) f[i][0]-=P;
    29         if(f[i][1]>=P) f[i][1]-=P;
    30     }
    31     printf("%d
    ",(f[n][0]+f[n][1])%P);
    32     return 0;
    33 }
    View Code

    2015年2月6日 15:38:06

     UPD: 本题也可用排列组合的方式计算

      枚举牝牛的数量a,那么一定至少有(a-1)*k头牡牛,那么除掉这(a-1)*k头牡牛,还剩下b=n-(a-1)*k-a头牡牛。

      这a头牝牛和b头牡牛是随便排的……也就是求一个多重全排列 即 (a+b)! / a!*b!

      这里的除法需用逆元来算

      逆元的计算方法是:已知a、p,求x满足 a*x≡1 (mod p) 那么根据费马小定理(或欧拉定理)可知x= pow(a,p-2)

    ps:由于我的方法是O(n)预处理出来所有的阶乘,所以时间复杂度上甚至不如上面那种DP的方法……求大神指导本题0msAC的正确姿势TAT

     1 /**************************************************************
     2     Problem: 3398
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:24 ms
     7     Memory:2052 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 3398
    11 #include<cstdio>
    12 #include<cstring>
    13 #include<cstdlib>
    14 #include<iostream>
    15 #include<algorithm>
    16 #define rep(i,n) for(int i=0;i<n;++i)
    17 #define F(i,j,n) for(int i=j;i<=n;++i)
    18 #define D(i,j,n) for(int i=j;i>=n;--i)
    19 using namespace std;
    20 int getint(){
    21     int v=0,sign=1; char ch=getchar();
    22     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
    23     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
    24     return v*sign;
    25 }
    26 /*******************template********************/
    27 typedef long long LL;
    28 const int P=5000011;
    29 LL pow(LL a,LL b,LL P){
    30     LL r=1,base=a%P;
    31     while(b){
    32         if (b&1) r=r*base%P;
    33         base=base*base%P;
    34         b>>=1;
    35     }
    36     return r;
    37 }
    38 LL p[100086];
    39 int main(){
    40     LL n=getint(),k=getint();
    41     p[0]=p[1]=1;
    42     F(i,2,n) p[i]=p[i-1]*i%P;
    43     LL ans=1+n;// 当a=0 ans=1,a=1,ans=n
    44     F(i,2,n){
    45         LL a=i,b=n-(i-1)*k-i;
    46         if (b<0) break;
    47         ans=(ans+p[a+b]*( pow(p[a]*p[b]%P,P-2,P) )%P)%P;
    48     }
    49     printf("%lld
    ",ans);  
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    自考新教材--p78
    自考新教材--p76_2
    自考新教材--p76_1
    自考新教材--p75
    自考新教材--p70
    自考新教材--p69
    以HTML5及其衍生技术为基础的B/S架构实时视频监控解决方案
    智能化安防视频监控行业发展是如何转变的?
    摄像头视频监控是如何与流媒体服务器云平台连接的?
    如何实现摄像头监控数据实时存储及传输?
  • 原文地址:https://www.cnblogs.com/Tunix/p/4276832.html
Copyright © 2020-2023  润新知