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

    题目大意

    一共有N个人,编号为 (1...N)

    题目要求给每一个人都要有一个属性,分别为 (R,P,G)

    并且对于这些属性的人有一定的要求:

    1.属性为 (G) 的人至少连续有 (m)

    2.最多有连续 (k) 个为 (R) 属性的人

    问符合这种要求的排列有多少个

    大致思路:

    这个题比较麻烦的是有两个条件,一个最多、一个最少。所以我们需要尽量把这两个条件变成一个条件。

    我们可以求出 (G) 最多长度为 (n)(R) 最多长度为 (k) 时的情况数,减去

    (G) 最多长度为 (m-1)(R) 最多长度为 (k) 时的情况数。

    相减结果就是答案。

    所以我们考虑一个 (DP[i][0...2]) 表示第 (i) 个人为 (R,P,G) 时的情况。

    下面以 (G) 来考虑 (DP) 式子的转移公式:

    (G) 最多长度为 (u) 时:

    (i<=u) 很明显,不存在非法的情况,所以状态直接可以进行转移:(dp[i][0] = dp[i-1][0]+dp[i-1][1]+dp[i-1][2])

    (下面为了方便将 (sum= dp[i-1][0]+dp[i-1][1]+dp[i-1][2])

    (i = u+1) 时,存在一种情况非法:即从 (1...i) 都是 (G) 。所以:

    $dp[i][0] = sum-1 $

    (i>u+1) 时。存在非法情况为:(G) 长度为 (u+1)

    这个非法情况的前提是:第 (i-u) 位是 (G)

    (i-u) 位是 (G) 的前提是: 第 (i-u-1) 位不是 (G)

    (i-u-1) 位不是 (G) ,那么肯定就是其他的两种情况。所以我们得出式子:

    $ dp[i][0] = sum - dp[i-u-1][1]-dp[i-u-1][2] $

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+7;
    const int mod=1e9+7;
    ll dp[maxn][3];
    int n,m,k;
    inline ll slove(int u,int k)
    {
        dp[0][0]=1;
        dp[0][2]=dp[0][1]=0;//什么都不放的时候,整体方案数为1
        for(int i=1;i<=n;++i){
            ll sum=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2]+mod)%mod;
            dp[i][2]=sum;
            if(i<=u)
                dp[i][0]=sum;
            else if(i==u+1)
                dp[i][0]=(sum-1+mod)%mod;
            else
                dp[i][0]=(sum-dp[i-u-1][1]-dp[i-u-1][2]+mod)%mod;
            if(i<=k)
                dp[i][1]=sum;
            else if(i==k+1)
                dp[i][1]=(sum-1+mod)%mod;
            else
                dp[i][1]=(sum-dp[i-k-1][0]-dp[i-k-1][2]+mod)%mod;
            //cout<<dp[i][0]<<" "<<dp[i][1]<<" "<<dp[i][2]<<endl;
        }
        return (dp[n][0]+dp[n][1]+dp[n][2]+mod)%mod;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        while(cin>>n>>m>>k)
        {
            cout<<((slove(n,k)-slove(m-1,k))%mod+mod)%mod<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    【SQL】含有NULL值的排序
    【SQL】结构化查询语言
    【Oracle】体系结构
    【PL/SQL】匿名块、存储过程、函数、触发器
    【Linux】VMware安装VMware Tools工具
    【SQL】INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND
    Tornado源码浅析
    【Python之路】特别篇--property()函数 和 @property 装饰符
    【Python之路】特别篇--生成器(constructor)、迭代器(iterator)、可迭代对象(iterable)
    【Python之路】特别篇--基于领域驱动模型架构设计的京东用户管理后台
  • 原文地址:https://www.cnblogs.com/SCaryon/p/9153263.html
Copyright © 2011-2022 走看看