题意:有三个兵种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. flush tables 好危险啊

    请看图 +----+------+-----------+------+------------+------+-------------------------+------------------ ...

  2. 谈谈HttpUrlConnection与DefaultHttpClient一些区别

    HttpClient封装的很庞大,很复杂,你必须按照,他封装的思想去使用它,导致它很不灵活. 相比之下,HttpUrlConnection很轻巧,很方便,很灵活. HttpClient对于数据上面的封 ...

  3. html5中插入视频和音频

    <audio src="1.mp3" controls></audio> <video src="1.mp4" controls& ...

  4. Show()和ShowDialog()

    show()仅仅是显示出来窗口界面而已```也就是和你执行的结果在同一窗口显示```所显示的窗口可以在后台运行```而showDialog()是一个对话框窗口界面```执行结果以新窗口界面出现```不 ...

  5. sublime text修改TAB缩进为2个空格

    打开sublime后在倒数第二项 preference---->Settings-user: 然后输入 "tab_size": 2, "translate_tabs ...

  6. HTML5自学笔记[ 4 ]js中新增的选择器方法

    querySelector():参数与jQuery一样,这个方法获取一组元素中的第一个元素. querySelectorAll():获取一组元素. getElementsByClassName():获 ...

  7. Qt之QSS(白色靓丽)

    简述 Qt助手中有关于各种部件的QSS详细讲解,资源很丰富,请参考:Qt Style Sheets Examples. 白色靓丽 - 一款漂亮的QSS风格. 你可以直接使用,也可以随意转载,但请务必保 ...

  8. P92认识对话框

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. Mybatis 实用

    1.<delete id="removeZtreeS" parameterType="String"> DELETE FROM sys_fun WH ...

  10. OpenTSDB介绍——基于Hbase的分布式的,可伸缩的时间序列数据库,而Hbase本质是列存储

    原文链接:http://www.jianshu.com/p/0bafd0168647 OpenTSDB介绍 1.1.OpenTSDB是什么?主要用途是什么? 官方文档这样描述:OpenTSDB is ...