zoukankan      html  css  js  c++  java
  • ZOJ 3747 Attack on Titans

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3747

    题意:

    现在有n个士兵进行排序,只有G、R、P三种士兵,要求至少有m个G士兵连续和至多k个R士兵连续,问可以有多少种排法。

    思路:

    由于题目中一个是至少,另一个是至多,所以先把至少改成至多:(至多有n个G士兵连续,k个R士兵连续)-(至多有m-1个士兵连续,k个士兵连续),这样一来,剩下的情况当中G士兵的个数就是【m,n】,满足至少有m个G士兵连续。

    d【i】【j】表示当前第i个人是j号兵种时的方法数。(G:0 ; R:1 ; P:2)

    由于当前方法数需要根据上一步推出来,那么上一步的方法数为sum=d【i-1】【0】+d【i-1】【1】+d【i-1】【2】。

    ①第i个人是P号兵种:

       这就很简单了,因为P兵种没有限制,所以直接d【i】【2】=sum。

    ②第i个人是G号兵种:  (u表示至多有u个G士兵连续)

       1)、如果i<=u,那么此时不可能出现u个G连续的情况,直接d【i】【1】=sum。

       2)、如果i=u+1,那么此时就会有前i个都为G的情况,而且只有这么一种情况,所以d【i】【1】=sum-1。

       3)、如果i>u+1,此时i-u~i-1就会出现都为G的情况,那么此时第i-u-1位就可以为R士兵和P士兵,所以d【i】【1】=sum-d【i-u-1】【1】-d【i-u-1】【2】。

    ③第i个是R号兵种:

       同理分析即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 1000000 + 5;
    17 
    18 const int mod=1000000007;
    19 
    20 int n,m,k;
    21 ll d[maxn][4];
    22 
    23 ll compute(ll u, ll v)
    24 {
    25     d[0][0]=1;
    26     d[0][1]=d[0][2]=0;
    27     for(int i=1;i<=n;i++)
    28     {
    29         ll sum = (d[i-1][0]+d[i-1][1]+d[i-1][2])%mod;
    30 
    31         //如果第i位是P
    32         d[i][2]=sum;
    33 
    34         //如果第i位是G
    35         if(i<=u)
    36             d[i][0]=sum;
    37         else if(i==u+1)
    38             d[i][0]=sum-1;
    39         else
    40             d[i][0]=sum-d[i-u-1][1]-d[i-u-1][2];
    41 
    42         //如果第i位是R
    43         if(i<=v)
    44             d[i][1]=sum;
    45         else if(i==v+1)
    46             d[i][1]=sum-1;
    47         else d[i][1]=sum-d[i-v-1][0]-d[i-v-1][2];
    48     }
    49     return (d[n][0]+d[n][1]+d[n][2])%mod;
    50 }
    51 
    52 int main()
    53 {
    54     //freopen("in.txt","r",stdin);
    55     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    56     {
    57         printf("%lld
    ",((compute(n,k)-compute(m-1,k))%mod+mod)%mod);
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    easy_install
    do some projects in macine learning using python
    awesome-scala
    val, lazy, def
    Scala命令设置JVM参数的规则
    CMMI-4中19个PA的大致描述
    项目管理中的十一个原则
    php代码在服务器中查看接值
    PHP进程锁
    解决百度网盘(百度云)分享链接不存在失效、分享的文件已经被取消的问题
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7203833.html
Copyright © 2011-2022 走看看