HDU 1297 Children’s Queue
生活随笔
收集整理的這篇文章主要介紹了
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?
轉載于:https://www.cnblogs.com/DriverLao/p/9457475.html
總結
以上是生活随笔為你收集整理的HDU 1297 Children’s Queue的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Nowcoder] 寻找子串
- 下一篇: asp.net 2.0 语言包 全球化