以前剛接觸ACM時做11頁,有挺多題不懂的。最近據某人說校納新賽和杭電11頁差不多,於是順便又回來補上,收穫不少,對遞推有了更深的理解.
| Solved |
Pro.ID |
Title |
Author |
Source |
(AC/Submit)Ratio |
|
2044 |
一隻小蜜蜂... |
lcy |
遞推求解專題練習(For Beginner) |
(7342/19929)36.84% |
|
2045 |
不容易系列之(3)—— LELE的RPG難題 |
lcy |
遞推求解專題練習(For Beginner) |
(6245/15736)39.69% |
|
2046 |
骨牌鋪方格 |
lcy |
遞推求解專題練習(For Beginner) |
(7318/15227)48.06% |
|
2047 |
阿牛的EOF牛肉串 |
lcy |
遞推求解專題練習(For Beginner) |
(5338/11408)46.79% |
|
2048 |
神、上帝以及老天爺 |
lcy |
遞推求解專題練習(For Beginner) |
(5231/12304)42.51% |
|
2049 |
不容易系列之(4)——考新郎 |
lcy |
遞推求解專題練習(For Beginner) |
(4456/11745)37.94% |
|
2050 |
折線分割平面 |
lcy |
遞推求解專題練習(For Beginner) |
(6391/9090)70.31% |
|
2045 ( 不容易系列之(3)—— LELE的RPG難題 )
#include<cstdio>#define MAXN 52__int64 arr[MAXN];int main(){ int n,i; arr[1]=3,arr[2]=6,arr[3]=6; for(i=4; i<MAXN; ++i) arr[i]=arr[i-1]+2*arr[i-2];/*arr[i]=arr[i-1]+2*arr[i-2];在arr[i]時,可以由arr[i-1]和arr[i-2]得到,arr[i-1]: 由於arr[i-1]和arr[1]不一樣,所以arr[i]只能選擇一種(arr[i]和arr[i-1]相鄰且要和arr[0]不同)arr[i-2]: 這時arr[i-1]不是最後一個,所以這個位置可以選兩種顏色(只要和arr[i-2]不同就行了), 選好後arr[i]就只能選一種。 */ while(scanf("%d",&n)==1){ printf("%I64d\n",arr[n]); } return 0;}
2046 ( 骨牌鋪方格
#include<cstdio>#define MAXN 52__int64 f[MAXN];int main(){ int i,n; f[0]=0, f[1]=1, f[2]=2; for(i=3; i<MAXN; ++i) f[i] = f[i-1]+f[i-2];/* f[i] = f[i-1]+f[i-2];f[i-1]: 只能加一塊豎著放的f[i-2]: 兩塊橫著疊在一起兩種都是只有一種情況*/ while(scanf("%d",&n)!=EOF){ printf("%I64d\n",f[n]); } return 0;}
2047
( 阿牛的EOF牛肉串 )
/*對於一串字元,分為兩種情況:(1) 不以O結尾的, 如EF,那麼它接下來有三種情況: EFF、EFE、EFO注意,有兩個是不以O結尾的,一個是以O結尾的(2) 以O結尾的,如EO,那麼它接下來只有兩種情況, EOF、EOE。且這兩種情況都不以O結尾那麼可以推匯出,對於某一次的情況,它以O結尾的個數是,上一次不以O結尾的個數不以O結尾的個數是上一次 “不以O結尾的”的兩倍 加上上次 “以O結尾的”的兩倍。可以得出遞推方程f1[i] = f2[i-1]; // f1儲存以O結尾的個數f2[i] = f1[i-1]*2+f2[i-1]*2; // f2儲存不以O結尾的個數得出了這兩個,總數也自然就求出來了f[i] = f1[i]+f2[i]; // f儲存總數*/#include<cstdio>#define MAXN 52__int64 f[MAXN],f1[MAXN],f2[MAXN];int main(){ int n,i; f1[1]=1,f2[1]=2,f[1]=3; // f1為以 O 結尾的個數,f2為以E、F結尾的個數 for(i=2; i<=40; ++i){ f1[i] = f2[i-1]; f2[i] = f1[i-1]*2+f2[i-1]*2; f[i] = f1[i]+f2[i]; } while(scanf("%d",&n)==1){ printf("%I64d\n",f[n]); } return 0;}
錯排公式(1462,2048,2049):
某人寫了n封信和n個信封,如果所有的信都裝錯了信封。求所有的信都裝錯信封,共有多少種不同情況。
分析思路:
1、當N=1和2時,易得解~,假設F(N-1)和F(N-2)已經得到,重點分析下面的情況:
2、當有N封信的時候,前面N-1封信可以有N-1或者 N-2封錯裝
3、前者,對於每種錯裝,可從N-1封信中任意取一封和第N封錯裝,故=F(N-1)*(N-1)
4、後者簡單,只能是沒裝錯的那封和第N封交換信封,沒裝錯的那封可以是前面N-1封中的任意一個,故= F(N-2) * (N-1)
基本形式:d[1]=0; d[2]=1
遞迴式:d[n]= (n-1)*( d[n-1] + d[n-2])
這就是著名的錯排公式。
2048
( 神、上帝以及老天爺 )
/*錯排公式全部抽錯的機率,即全部排錯的情況個數除與的全排列個數*/#include<cstdio>#define MAXN 52__int64 f[MAXN],f1[MAXN],f2[MAXN];double ans[MAXN];int main(){ int C,n,i; f[1]=0,f[2]=1; __int64 sum=2; ans[2]=0.5; for(i=3; i<=20; ++i){ sum *= i; f[i] = (i-1)*(f[i-1]+f[i-2]); ans[i] = f[i]*1.0/sum; } scanf("%d",&C); while(C--){ scanf("%d",&n); printf("%.2f%%\n",ans[n]*100); } return 0;}
—— 生命的意義,在於賦予它意義。
原創 http://blog.csdn.net/shuangde800 , By
D_Double