Collection Game
Time Limit: 1000 MS Memory Limit: 128000 K
Total Submit: 31(14 users) Total Accepted: 13(13 users) Rating: Special Judge: No
Description
POI and POJ are pair of sisters, one is a master in “Kantai Collection”, another is an excellent competitor in ACM programming competition. One day, POI wants to visit POJ, and the pace that between their homes is made of square bricks. We can hypothesis that POI’s house is located in the NO.1 brick and POJ’s house is located in the NO.n brick. For POI, there are three ways she can choose to move in every step, go ahead one or two or three bricks. But some bricks are broken that couldn’t be touched. So, how many ways can POI arrive at POJ’s house?
Input
There are multiple cases.
In each case, the first line contains two integers N(1<=N<=10000) and M (1<=M<=100), respectively represent the sum of bricks, and broke bricks. Then, there are M number in the next line, the K-th number ak means the brick at position a[k] was broke.
Output
Please output your answer P after mod 10007 because there are too many ways.
Sample Input
5 1
3
Sample Output
3
题意:从POI走到POJ家要走过n个砖块,其中m个砖块是坏掉的,不能走,POI有三种走砖块的方法,一次走一格,一次走两格,一次走三格,问有多少种到达POJ家的方法
简单递推,和走台阶问题是一样的,甚至同样给是三种基础行走方法,也就多了个坏掉砖块的条件,直接把坏掉砖块的方法数在递推时变为0,就相当于坏掉的没走过了,然后继续递推就好
#include<stdio.h>
#include<string.h>
int main()
{
int n,m,k,i,a[10008];///递推数组
bool vis[10008];///标记数组,可以快速记录并找出当前砖块是否broken
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(vis,false,sizeof(vis));///初始化标记数组
for(i=1; i<=m; i++)
{
scanf("%d",&k);///标记
vis[k]=true;
}
a[2]=1;///递推边界
a[3]=2;
a[4]=4;
for(i=2; i<=n; i++)///从第二块砖开始计入方法数
{
if(i<=4)///小于4的砖块是边界点,应特殊考虑,防止被broken归零后导致末尾递推混乱
{
if(i==2)///就是1种方法,变成0也行,不影响
a[i]=1;
if(i==3)///因为第二个砖块的方法数是动态变化的,因此是决定了第二个砖块是否broken后,再由第二个砖块推出第三个
a[i]=a[i-1]+1;///是前面的砖块方法数+1 (加上的是一次两步的方法)
if(i==4)///由前两个砖块方法数推出,因为前两个方法数也不是固定的,因此递推相加而得
a[i]=a[i-1]+a[i-2]+1;///加上一步走三个的方法
}
else///普通情况直接递推即可
a[i]=(a[i-1]+a[i-2]+a[i-3])%10007;///记得求模
if(vis[i]==true)///判断当前遍历的砖块是否broken,若broken则归零
a[i]=0;
}
printf("%d\n",a[n]);
}
return 0;
}