11310:DELIVERY DEBACLE
問題文
http://uva.onlinejudge.org/external/113/11310.html
o oo o
の二つで縦2,幅nのブロックを作るパターン数を求めよ。
↓類題。
http://d.hatena.ne.jp/TobiasGSmollett/20130618/1371579981
ooooooooo ooooooooo のように長さnのパターン数をf[ n ], ooooooooo oooooooo のように長さnの長方形から一個無くした形のパターン数をg[ n ]とすると f[n]を作るのにAの部分を使ったとすると、f[ n ]は Aooooooo oooooooo g[ n ] + oooooooo Aooooooo g[ n ] + AAoooooo Aooooooo g[ n - 1 ] + Aooooooo AAoooooo g[ n - 1 ] - Aooooooo Aooooooo f[ n - 1 ] で求まる。最初のg[ n ]2個で Aooooooo Aooooooo を2回数えてしまっているのでf[ n-1 ]を引く。 g[ n ]は ooooooo Aooooooo f[ n - 1 ] + Aoooooo AAoooooo f[ n - 2 ]
よって、
g[ i ] = f[ i - 1 ] + f[ i - 2 ]
f[ i ] = 2 * g[ i ] + 2 * g[ i - 1 ] - f[ i - 1 ]
問題文より、
f[ 1 ] = 1, f[ 2 ] = 5, g[ 2 ] = 2
とした。
#include<iostream> using namespace std; typedef long long ll; ll f[41],g[41],t,n; int main(void){ f[1]=1,f[2]=5,g[2]=2; for(int i=3;i<41;i++){ g[i]=f[i-1]+f[i-2]; f[i]=2*(g[i]+g[i-1])-f[i-1]; } cin >> t; while(t--){ cin >> n; cout << f[n] << endl; } return 0; }
n=1のとき o o の1通り。 n=2のとき AA AA oA Ao Ao oA AA AA の4通り。 n=3のとき AAB ABB ABB AAB の2通り。
n=3までのパターンで全部のブロックが作れる。
だから、dp[ 0 ] = 1として
dp[ i + 1 ] += dp[ i ] * 1
dp[ i + 2 ] += dp[ i ] * 4
dp[ i + 3 ] += dp[ i ] * 2
とやっても解ける。
#include<iostream> using namespace std; typedef long long ll; ll t,n,dp[45]; int main(void){ dp[0]=1; for(int i=0;i<45;i++){ dp[i+1]+=dp[i]; dp[i+2]+=dp[i]*4; dp[i+3]+=dp[i]*2; } cin >> t; while(t--){ cin >> n; cout << dp[n] << endl; } return 0; }