题意:有三个兵种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. base64 数据处理

    base64 数据处理 1. base64 字母表 2. 原理 处理原理 http://baike.baidu.com/view/469071.htm 3. iOS上的应用 iOS7 之前使用http ...

  2. noip2016题解汇总

    [uoj#260]玩具谜题 传送门 http://uoj.ac/problem/260 分析 模拟. int n,m; int dir[N]; char nam[N][L]; int a[M],s[M ...

  3. 终端执行python shell的方法

    假设有一个Py文件,放在下PycharmProjects/learn下,文件名是 myfile.py. 1.打开终端输入python3进入2.在shell下 输入import sys 回车3.输入 s ...

  4. 转 http://www.5icool.org/a/201106/a654.html CSS开发中常用的公用样式

    overflow:hidden 隐藏溢出 一.自己总结的公用样式解析 html, body, div, p, ul, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, f ...

  5. 笔记13:File 类的一些操作

    一.对文件的创建(create) private void button1_Click(object sender, EventArgs e) { File.Create(@"F:\\QQP ...

  6. HDUOJ----2485 Destroying the bus stations(2008北京现场赛A题)

    Destroying the bus stations                                                                          ...

  7. MYSQL 日期函数【转】

    MySQL日期时间函数大全 DAYOFWEEK(date) 返回日期date是星期几(=星期六,ODBC标准) mysql> select DAYOFWEEK('1998-02-03'); WE ...

  8. 如何删除href=""中的链接?

    答案:在dw中操作,删除 HTML文件的href的链接地址\href="[^"]*"href="" 同理可以在title="[^" ...

  9. WPF TreeView的使用

    WPF提供了treeView控件,利用该控件开发者可以将数据分层显示在树结构中.当然其中需要用到Binding的机制,有用的类包括:ObjectDataProvider.DataTemplate.Hi ...

  10. eclipse debug 过滤一些包

    eclipse debug java程序的时候, 我们按F5的时候,常常会进入java自带类库里,这些类库并不是我们需要debug的代码,这样会影响debug的效率,我们可以在eclipse里设置,过 ...