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 ...
随机推荐
- Principle and Application of Database System
<数据库系统原理与应用>课程教学大纲 英文名称:Principle and Application of Database System 课程类型:专业必修课 学时/学分:48+16/3. ...
- hadoop分布式的环境搭建
版本: 使用hadoop1.1.2 JDK为java7 1.下载hadoop 2.配置hadoop文件 3测试 1.下载hadoop: 1.1 在https://archive.apache.o ...
- iOS开发之——从零开始完成页面切换形变动画
前言 某天我接到了UI发给我的两张图: 需求图.png 看到图的时候我一脸懵逼,显然我需要做一个页面切换的指示动画.老实说,从大三暑假开始做iOS开发也一年有余了,但是遇到复杂动画总是唯恐避之不及,只 ...
- Java 之 I/O 系列 02 ——序列化(一)
Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 一 序列化概述 序 ...
- javascript function new this
1. 首先,我们这里把function直接调用时将这个function当做方法来看待,而new function是将function当做类来看待 2. 当把function作为类来使用时,functi ...
- SecureCRT快捷键
ctrl + a : 移动光标到行首ctrl + e :移动光标到行尾crtl + b: 光标前移1个字符crtl + f : 光标后移1个字符 crtl + h : 删除光标之前的一个字符c ...
- 关于jquery计算页面元素数量
这段jquery计算页面元素数量代码,能不能刷新页面直接输出数量,而不用点计算按钮 <scriptsrc="http://ajax.googleapis.com/ajax/libs/j ...
- 如何在android项目中引用project作为类库引用
前言: 在我们开发项目的时候,存在很多多个项目共有一个资源.逻辑代码的情况,这种情况一般我们采用在开发项目中导入别的项目作为引用的类库.资源等. 操作: 1. 新建一个android项目common ...
- jmeter内存溢出
当我用jmeter来测试elasticsearch性能的时候,发生过三种性质的内存溢出. 1. index 由于数据流过大,内存使用超过jmeter默认的上限,就溢出了. 用记事本打开jmeter.b ...
- Javascript arguments详解
今天我们来看看arguments对象及属性.arguments对象不能显式创建,arguments对象只有函数开始时才可用.函数的 arguments 对象并不是一个数组,访问单个参数的方式与访问数组 ...