• ZOJ


    题意就是输入三个数字 n m k,  给n个士兵排队

    每个士兵三种G,R,P可选,求至少有m个连续的G士兵和最多有k个连续的R士兵的排列总和

    分析题意:在n个士兵中至少有m个连续的G士兵和最多有k个连续的R士兵的排列总和

    就等于 (在n个士兵中最多有k个连续的R士兵和最多有n个连续的G士兵) - (在n个士兵中最多有k个连续的R士兵和最多有m-1个连续的G士兵)

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstdlib>
    #include<string>
    #include<string.h>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #include<bitset>
    #include<cmath>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define LL long long
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #define M 1000000007
    using namespace std;
    
    #define Maxn 1100000
    
    LL dp[Maxn][5]; //dp[i][0]表示第i个为G,至多有u个连续G,至多有v个连续R的个数
                    //dp[i][1]表示第i个为R,....
                    //dp[i][2]表示第i个为P,....
    LL n,m,k,u,v;
    
    LL Cal()
    {
        dp[0][0]=1; //初始状态
        dp[0][1]=0;
        dp[0][2]=0;
    
        for(int i=1;i<=n;i++)
        {
           LL sum=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])%M;
           dp[i][2]=sum;
    
           if(i<=u)
                dp[i][0]=sum;
           else if(i==u+1)
                dp[i][0]=(sum-1)%M;
           else
                dp[i][0]=(sum-dp[i-u-1][1]-dp[i-u-1][2])%M;
    
           if(i<=v)
                dp[i][1]=sum;
           else if(i==v+1)
                dp[i][1]=(sum-1)%M;
           else
                dp[i][1]=(sum-dp[i-v-1][0]-dp[i-v-1][2])%M;
    
           //printf("u:%lld v:%lld i:%d %lld %lld %lld
    ",u,v,i,dp[i][0],dp[i][1],dp[i][2]);
           //system("pause");
    
        }
        return (dp[n][0]+dp[n][1]+dp[n][2])%M;
    }
    
    
    int main()
    {
       //freopen("in.txt","r",stdin);
       //freopen("out.txt","w",stdout);
       while(~scanf("%lld%lld%lld",&n,&m,&k))
       {
           LL ans;
           u=n,v=k;
           ans=Cal();
    
           //printf(":%lld
    ",ans);
           //system("pause");
    
           u=m-1,v=k;
           //printf(":%lld
    ",Cal());
           //system("pause");
           ans=((ans-Cal())%M+M)%M;
           printf("%lld
    ",ans);
    
    
       }
       return 0;
    }
  • 相关阅读:
    Java:线程的六种状态及转化
    Java:多线程概述与创建方式
    小白学Java:RandomAccessFile
    如何用IDEA开启断言
    如何通过IDEA添加serialVersionUID
    小白学Java:I/O流
    更改IDEA相对路径
    小白学Java:File类
    小白学Java:内部类
    Leetcode数组题*3
  • 原文地址:https://www.cnblogs.com/tonyyy/p/10432896.html
Copyright © 2020-2023  润新知