鋪地磚(找遞推式 + 大數)
阿新 • • 發佈:2018-12-16
鋪地磚
時間限制: 1 Sec 記憶體限制: 128 MB
題目描述
一天,晨晨的數學老師佈置了一道題目,大意如下:用1×1和2×2的磁磚不重疊地鋪滿n×3的地板,共有多少種方案?
例如:n=1時:1×3的地板方法就一個,直接由三個1×1的磁磚鋪滿。
n=2時:2×3的地板可以由下面3種方案鋪滿:
輸入
第一行:一個整數n(1≤n≤100)。
輸出
輸出鋪滿n×3的地板的方案數。
樣例輸入
複製樣例資料
3
樣例輸出
5
提示
對於20%的資料,1≤n≤15;
對於50%的資料,1≤n≤30;
對於100%的資料,1≤n≤100;
設寬為n的時候方案數為f[n];
根據這張圖可以發現,寬為2,長為3的有3種方法。由於長是固定為3的,那麼當寬大於2的時候,可以試著找
通過n-1,n-2的寬度來找,去掉n-1行,那麼就剩下最後一行,只能鋪1*1的磚3塊,所以為f[n-1];去掉n-2行,那麼還剩下兩行,也就只有上面三種方法,是3種嗎,看方法三,和去掉n-1行重複了,所以只有2種方法為2*f[n-2];
所以總共f[n]=f[n-1]+2*f[n-2];
由於資料太大,用大數做。
/**/ #include <cstdio> #include <cstring> #include <cmath> #include <cctype> #include <iostream> #include <algorithm> #include <map> #include <set> #include <vector> #include <string> #include <stack> #include <queue> typedef long long LL; using namespace std; int f[105][10005]; int n; void solve(int a[], int b[], int c[]){ for (int i = 1; i <= b[0]; i++){ a[i] += 2 * b[i]; if(a[i] > 9){ a[i + 1] += a[i] / 10; a[i] %= 10; } } int len = b[0]; while(a[len + 1]) len++; for (int i = 1; i <= c[0]; i++){ a[i] += c[i]; if(a[i] > 9){ a[i + 1]++; a[i] -= 10; } } int cnt = c[0]; while(a[cnt + 1]){ if(a[cnt + 1] > 9){ a[cnt + 2]++; a[cnt + 1] -= 10; cnt++; }else{ cnt++; break; } } a[0] = max(cnt, len); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); scanf("%d", &n); f[1][0] = 1, f[1][1] = 1, f[2][0] = 1, f[2][1] = 3; for (int i = 3; i <= n; i++){ solve(f[i], f[i - 2], f[i - 1]); } for (int i = f[n][0]; i >= 1; i--) printf("%d", f[n][i]); printf("\n"); return 0; } /**/