| 方格涂色 | ||||||
| ||||||
| Description | ||||||
|
有一条有n个方格的直线,方格标号从1到N,将所有方格涂成两种颜色红或者蓝。 并且要求至少连续M个方格是红色。问有多少种方案数。 | ||||||
| Input | ||||||
|
有多组测试数据 对于每组测试数据,输入两个整数N和M(0<N,M<=100000)。 | ||||||
| Output | ||||||
| 方案数对1000000007取模。 | ||||||
| Sample Input | ||||||
| 4 3 | ||||||
| Sample Output | ||||||
| 3 |
思路:
1、统计计数问题,我们考虑dp,设定dp【i】表示长度为i的合法方案数。
那么考虑其状态转移方程:
①我们首先考虑递推式,那么对应可以先手写样例来递推(O代表红色,X代表蓝色):
2 2:
OO
3 2(我们可以在2 2的基础上,后边加一个X,和一个O):
OOX
OOO
这里就能够构成两种情况,那么显然我们还可以在OO的最前边加O或者是X
XOO
OOO
很明显,在前边加O的方案重复了,那么此时只有三种合法情况:
OOX
OOO
XOO
我们接下来考虑4 2(我们还可以在3 2的基础上,后边加一个X,和一个O):
OOXX
OOOX
XOOX
OOXO
OOOO
XOOO
这里就能够构成六种情况,那么显然我们可以在OO的最前边加OO,OX,XX,XO:OOOO
OXOO
XXOO
XOOO
其中重复了两种情况,那么去除之后剩下八种合法情况:
OOXX
OOOX
XOOX
OOXO
OOOO
XOOO
OXOO
XXOO
2、通过分析和列举我们能够知道这样一个问题:
我们在手写样例的时候,我们可以在上一个情况的基础上,在序列末尾加上一个蓝色方块或者是红色方块。
然后再在M个红色方块前边加上2的平方次种情况,再去重即可。
再通过大量的分析能够得到一个结论,在连续个M红色方块前边加上2的平方次种的情况的时候去重之后,直接相连的那个位子一定是X
比如:
OOO,如果我们假如想要得到一个长度为5的结果:
XOOOO
XXOOO
OOOOO
OXOOO
很显然,OOOOO,XOOOO两种情况是一定重复过的。
3、那么我们考虑上述过程,可以大概写出来一个框架:
dp【i】=dp【i-1】*2+2^(i-m-1)【减一的目的就是在连续的O前边,先加上一个X,再考虑前边的部分】-?【这里?表示还需要对一部分进行去重】
那么我们接下来再考虑从4 2递推到5 2:
(4 2的合法情况:)
OOXX
OOOX
XOOX
OOXO
OOOO
XOOO
OXOO
XXOO
我们知道,去重的部分,肯定是在前边加东西的时候加重复的部分要去除,那么我们考虑加上:OOXOO
OXXOO
XOXOO
XXXOO
这四种是可以加进来的,考虑哪个情况是会重复的呢?
显然是OOXOO的情况重复了。那么考虑长度为2的时候dp值:dp【2】=1;我们肯定有方案是冲dp【2】一直递推过来的,就是说最开头的两个O一定会通过递推得到过OOXOO,所以这个?就是dp【i-m-1】;
4、那么状态转移方程就是:
dp【i】=①dp【i-1】*2+②2^(i-m-1)-③dp【i-m-1】;
①直接在长度为i-1的所有方案数的基础上,后边加上一个O或者X,所以是乘以2.
②接下来在连续M个O前边加上N-M个情况的时候,肯定紧挨着的那个要放X,所以是考虑2^(i-m-1)种情况。
③再接下来对于2^(i-m-1)种情况进行去重,去重部分就是dp【i-m-1】;因为肯定有dp【i-m-1】这些情况递推出来一系列已有情况,所以要去重。
5、这个题真的很不错啊!
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll long long int
#define mod 1000000007
ll dp[150000];
ll b[150000];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<=n;i++)
{
if(i==0)b[i]=1;
else
{
b[i]=(b[i-1]*2)%1000000007;
}
}
memset(dp,0,sizeof(dp));
dp[m]=1;
for(int i=m+1;i<=n;i++)
{
dp[i]=((dp[i-1]*2)+b[i-m-1]-dp[i-m-1]+mod)%mod;
}
printf("%d\n",(dp[n]+mod)%mod);
}
}

探讨一种经典的动态规划问题——方格涂色。在一条由N个方格组成的直线上,每个方格可涂成红或蓝两色,但必须确保至少连续M个方格为红色。本文详细解析如何利用动态规划求解该问题的有效方案数量。

995

被折叠的 条评论
为什么被折叠?



