题意:有三个兵种R,G,C,选取N个排成一列,要求G至少有M个连续的,R至多有K个连续的,问有多少种排列方式。

此题与UVa 10328 - Coin Toss非常相似,都是问某个字符连续出现的种数。题中问至少连续的排列个数可以转化为至多连续来计算,但是难点在于这次需要算两个连续的兵种,而且有三个兵种。

试着从那个题的角度考虑,最终的答案可以是这样:N个士兵中,G至多连续N个、R至多连续K个的排列个数 减去 G至多连续M-1个、R至多连续K个的排列个数。

我们要考虑计算的时候G与R是否相互影响,这样需要分开表示。

设dp[i][j]表示前i个士兵,当第i个士兵是第j种兵(假设R:0,G:1,C:2)时,G至多连续u个、R至多连续v个的排列个数。

对于不作要求的C士兵,它可以由第i-1阶段的三种士兵任意转移:dp[i][2]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]。

对于G种兵,当i<=u时,无论怎么转移都不会出现非法状态:dp[i][0]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]。

当i==u+1,这个时候非法状态是从第1个位置到第u个位置全都是G,只有这一种情况,dp[i][0]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]-1。

当i>u+1,此时非法状态是从第i-u个位置到第u个位置全都是G,这种状态可以第i-u-1个位置是R和C的状态转移而来,dp[i][0]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]-dp[i-u-1][1]-dp[i-u-1][2]。

对于R种兵,与G种兵类似,当i<=v时,无论怎么转移都不会出现非法状态:dp[i][1]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]。

当i==v+1,这个时候非法状态是从第1个位置到第v个位置全都是R,只有这一种情况,dp[i][1]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]-1。

当i>v+1,此时非法状态是从第i-u个位置到第v个位置全都是R,这种状态可以第i-v-1个位置是G和C的状态转移而来,dp[i][1]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]-dp[i-v-1][0]-dp[i-v-1][2]。

初始化,dp[0][0]=1,dp[0][1]=dp[0][2]=0;

这样,我们令u分别等于N和m-1,v等于k,进行两次递推,得到的结果相减即是答案。

注意减法可能出现负数,取模的时候要特别处理一下。

 #include<iostream>
 #include<vector>
 #include<cmath>
 #include<cstdio>
 #define MOD 1000000007
 #define ll long long
 using namespace std;
 ll dp[][];
 int main()
 {
     int n,m,k;
     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
     {
         dp[][]=;
         ; i<=n; ++i)
         {
             dp[i][]=dp[i][]=dp[i][]=;
             ; j<; ++j)
             {
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
             }
             ) dp[i][]=(dp[i][]-)%MOD;
             ]=(dp[i][]-dp[i-k-][]-dp[i-k-][]+*MOD)%MOD;
         }
         ll sum=(dp[n][]+dp[n][]+dp[n][])%MOD;
         m--;
         ; i<=n; ++i)
         {
             dp[i][]=dp[i][]=dp[i][]=;
             ; j<; ++j)
             {
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
                 dp[i][]+=dp[i-][j];
                 dp[i][]%=MOD;
             }
             ) dp[i][]=(dp[i][]-)%MOD;
             ]=(dp[i][]-dp[i-k-][]-dp[i-k-][]+*MOD)%MOD;
             ) dp[i][]=(dp[i][]-)%MOD;
             ]=(dp[i][]-dp[i-m-][]-dp[i-m-][]+*MOD)%MOD;
         }
         ll res=(dp[n][]+dp[n][]+dp[n][])%MOD;
         printf("%lld\n",((sum-res)%MOD+MOD)%MOD);
     }
     ;
 }

考虑一下这个题与UVa 10328 - Coin Toss的异同。

在表示状态的时候,本题更加细致。在上个题中,减去非法状态时,需要得到某个以F为最后位置的状态,这个状态可以由上个阶段(不需考虑F或H)直接*2转移而来。

本题中,减去非法状态需要得到某个以非G为最后位置的状态,不同于上个题中除了H就是F,这个题有三种兵,虽然以C为尾容易转移得到,但以R为尾的却不能直接从上阶段转移过来。所以在状态中直接保存。

ZOJ 3747 - Attack on Titans (递推)的更多相关文章

  1. ZOJ 3747 Attack on Titans

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3747 题意: 现在有n个士兵进行排序,只有G.R.P三种士兵,要求至少有m ...

  2. LA 3516(ZOJ 2641) Exploring Pyramids(递推 DP)

    Exploring Pyramids Archaeologists have discovered a new set of hidden caves in one of the Egyptian p ...

  3. ACM学习历程—ZOJ 3777 Problem Arrangement(递推 && 状压)

    Description The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem sett ...

  4. 递推DP(至少和至多之间的转换

    UVa 10328 - Coin Toss 题意:给你一个硬币,抛掷n次,问出现连续至少k个正面向上的情况有多少种. 转换成抛N次至多连续有N个减去抛N次至多连续有K-1个1的情况 dp[i][k]表 ...

  5. zoj 3747 递推dp

    Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced ...

  6. attack on titans(动态规划递推,限制条件,至少转至多方法,进击的巨人)

    题目意思: 给n个士兵排队,每个士兵三种G.R.P可选,求至少有m个连续G士兵,最多有k个连续R士兵的排列的种数. 原题 Attack on Titans Time Limit: 2 Seconds ...

  7. ZOJ 3690 &amp; HDU 3658 (矩阵高速幂+公式递推)

    ZOJ 3690 题意: 有n个人和m个数和一个k,如今每一个人能够选择一个数.假设相邻的两个人选择同样的数.那么这个数要大于k 求选择方案数. 思路: 打表推了非常久的公式都没推出来什么可行解,好不 ...

  8. ZOJ 3182 HDU 2842递推

    ZOJ 3182 Nine Interlinks 题目大意:把一些带标号的环套到棍子上,标号为1的可以所以操作,标号i的根子在棍子上时,只有它标号比它小的换都不在棍子上,才能把标号为i+1的环,放在棍 ...

  9. ACM学习历程——ZOJ 3822 Domination (2014牡丹江区域赛 D题)(概率,数学递推)

    Description Edward is the headmaster of Marjar University. He is enthusiastic about chess and often ...

随机推荐

  1. Principle and Application of Database System

    <数据库系统原理与应用>课程教学大纲 英文名称:Principle and Application of Database System 课程类型:专业必修课 学时/学分:48+16/3. ...

  2. hadoop分布式的环境搭建

    版本: 使用hadoop1.1.2    JDK为java7 1.下载hadoop 2.配置hadoop文件 3测试 1.下载hadoop: 1.1 在https://archive.apache.o ...

  3. iOS开发之——从零开始完成页面切换形变动画

    前言 某天我接到了UI发给我的两张图: 需求图.png 看到图的时候我一脸懵逼,显然我需要做一个页面切换的指示动画.老实说,从大三暑假开始做iOS开发也一年有余了,但是遇到复杂动画总是唯恐避之不及,只 ...

  4. Java 之 I/O 系列 02 ——序列化(一)

    Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 一 序列化概述 序 ...

  5. javascript function new this

    1. 首先,我们这里把function直接调用时将这个function当做方法来看待,而new function是将function当做类来看待 2. 当把function作为类来使用时,functi ...

  6. SecureCRT快捷键

    ctrl + a :  移动光标到行首ctrl + e :移动光标到行尾crtl + b:  光标前移1个字符crtl + f :  光标后移1个字符 crtl + h :  删除光标之前的一个字符c ...

  7. 关于jquery计算页面元素数量

    这段jquery计算页面元素数量代码,能不能刷新页面直接输出数量,而不用点计算按钮 <scriptsrc="http://ajax.googleapis.com/ajax/libs/j ...

  8. 如何在android项目中引用project作为类库引用

    前言: 在我们开发项目的时候,存在很多多个项目共有一个资源.逻辑代码的情况,这种情况一般我们采用在开发项目中导入别的项目作为引用的类库.资源等. 操作: 1.  新建一个android项目common ...

  9. jmeter内存溢出

    当我用jmeter来测试elasticsearch性能的时候,发生过三种性质的内存溢出. 1. index 由于数据流过大,内存使用超过jmeter默认的上限,就溢出了. 用记事本打开jmeter.b ...

  10. Javascript arguments详解

    今天我们来看看arguments对象及属性.arguments对象不能显式创建,arguments对象只有函数开始时才可用.函数的 arguments 对象并不是一个数组,访问单个参数的方式与访问数组 ...