HDU 1297 Children’s Queue

【题意概述】

  有n个位置,每个位置可以放F或者M,规定一种合法的放置方案为不存在单独的F(即每个F的左边或者右边必须至少有一个F),问有多少种放置方案。

【题解】

  假设有一种合法的放置方案,有n-1个位置,那么我们在末尾多放一个M,必定是一个合法的方案。(放F则不一定)

  有n-2个位置的合法放置方案,我们在末尾多放FF,必定是一个合法的方案。(其实放MM也是必定合法的,但是会和上一种情况重复,不能考虑进去。FM和MF则不能保证合法)

  有n-2个位置的不合法放置方案,如果能够通过放置两个位置变成合法的,那么它一定以MF结尾,我们可以放置FF或者FM。也就是在n-4个位置的合法方案后面放置MFFM或者MFFF,但是MFFM会与第一种情况重复,所以我们只计算MFFF的。

  那么我们就可以得出递推式:f[i]=f[i-1]+f[i-2]+f[i-4],(i≥4).

  题目没有取模,所以我们要写成大数加法。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 #define N 1001
 6 #define rg register
 7 using namespace std;
 8 int n,f[N][N]; 
 9 inline int read(){
10     int k=0,f=1; char c=getchar();
11     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
12     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
13     return k*f;
14 }
15 inline void Pre(){
16     for(rg int i=1;i<=4;i++) f[i][0]=1;
17     f[1][1]=1; f[2][1]=2; f[3][1]=4; f[4][1]=7;
18 }
19 inline void add(int x,int y){
20     int len=max(f[x][0],f[y][0]);
21     for(rg int i=1;i<=len;i++) f[x][i]+=f[y][i];
22     for(rg int i=1;i<=len;i++)if(f[x][i]>9){
23         int tmp=f[x][i]/10;
24         f[x][i]%=10;
25         f[x][i+1]+=tmp;
26     }
27     while(f[x][len+1]>0) len++;
28     f[x][0]=len;
29 }
30 inline void Work(){
31     for(rg int i=5;i<=N;i++){
32         add(i,i-4);
33         add(i,i-2);
34         add(i,i-1);
35     }
36 }
37 int main(){
38     Pre();
39     Work();
40     while(scanf("%d",&n)!=EOF){
41         int len=f[n][0];
42         for(rg int i=len;i;i--) printf("%d",f[n][i]);
43         puts("");
44     }
45     return 0;
46 }
View Code

  

猜你喜欢

转载自www.cnblogs.com/DriverLao/p/9457475.html