ZOJ 3747 - Attack on Titans (递推)
题意:有三个兵种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 (递推)的更多相关文章
- ZOJ 3747 Attack on Titans
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3747 题意: 现在有n个士兵进行排序,只有G.R.P三种士兵,要求至少有m ...
- LA 3516(ZOJ 2641) Exploring Pyramids(递推 DP)
Exploring Pyramids Archaeologists have discovered a new set of hidden caves in one of the Egyptian p ...
- ACM学习历程—ZOJ 3777 Problem Arrangement(递推 && 状压)
Description The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem sett ...
- 递推DP(至少和至多之间的转换
UVa 10328 - Coin Toss 题意:给你一个硬币,抛掷n次,问出现连续至少k个正面向上的情况有多少种. 转换成抛N次至多连续有N个减去抛N次至多连续有K-1个1的情况 dp[i][k]表 ...
- zoj 3747 递推dp
Attack on Titans Time Limit: 2 Seconds Memory Limit: 65536 KB Over centuries ago, mankind faced ...
- attack on titans(动态规划递推,限制条件,至少转至多方法,进击的巨人)
题目意思: 给n个士兵排队,每个士兵三种G.R.P可选,求至少有m个连续G士兵,最多有k个连续R士兵的排列的种数. 原题 Attack on Titans Time Limit: 2 Seconds ...
- ZOJ 3690 & HDU 3658 (矩阵高速幂+公式递推)
ZOJ 3690 题意: 有n个人和m个数和一个k,如今每一个人能够选择一个数.假设相邻的两个人选择同样的数.那么这个数要大于k 求选择方案数. 思路: 打表推了非常久的公式都没推出来什么可行解,好不 ...
- ZOJ 3182 HDU 2842递推
ZOJ 3182 Nine Interlinks 题目大意:把一些带标号的环套到棍子上,标号为1的可以所以操作,标号i的根子在棍子上时,只有它标号比它小的换都不在棍子上,才能把标号为i+1的环,放在棍 ...
- ACM学习历程——ZOJ 3822 Domination (2014牡丹江区域赛 D题)(概率,数学递推)
Description Edward is the headmaster of Marjar University. He is enthusiastic about chess and often ...
随机推荐
- python 暴力破解密码脚本
python 暴力破解密码脚本 以下,仅为个人测试代码,环境也是测试环境,暴力破解原理都是一样的, 假设要暴力破解登陆网站www.a.com 用户 testUser的密码, 首先,该网站登陆的验证要支 ...
- SAP标准价格修改
标准MR21修改前期的价格,不会影响到当期. 相关配置 事务码OMRN. 如企业账期已经开到 2015 年 2 月,会计账期还可对 1月记账,配置后可修改1月物料价格.
- flush tables 好危险啊
请看图 +----+------+-----------+------+------------+------+-------------------------+------------------ ...
- 【转】 C++中的new VS C语言中的malloc
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 前几天一个朋友去面试百度空间的一个职位,被问及这个问题,我听后说了几点,不过感觉还是不透彻,所以上网查阅了一些资 ...
- C语言中随机数相关问题
用C语言产生随机数重要用到rand函数.srand函数.及宏RAND_MAX(32767),它们均在stdlib.h中进行了声明. int rand(void);//生成一个随机数 voidsrand ...
- ajax 动态获取json的例子
1.前台脚本: //用于切换图片列表的ajax function changePhoto(title,hotelId){ $.ajax({ contentType: "application ...
- 《Java程序设计》第三周学习总结
20145224-陈颢文 <Java程序设计>第三周学习总结 教材学习内容总结 一.定义类: ·类定义时使用class关键字,要对类中变量(值域成员/对象数据成员)行类型声明. class ...
- 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝
js 对象 浅拷贝 和 深拷贝 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor ...
- struts2视频学习笔记 22-23(基于XML配置方式实现对action的所有方法及部分方法进行校验)
课时22 基于XML配置方式实现对action的所有方法进行校验 使用基于XML配置方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类 ...
- go——beego的数据库增删改查
一直都不理解使用go语言的时候,为什么还要自己去装beego,以为使用go便可以解决所有的问题,结果在朋友的点拨下,才意识到: go与beego的关系就好比是nodejs与thinkjs的关系,因此也 ...