題解
該題考察經典演算法,可我還是太菜了...,不會做/(ㄒoㄒ)/~~。
正解應該是dp + 字首和優化,只解 n == 1 或暴力 dp 都會超時,怎麼看出來的呢?
f[i][j][k] 表示第 i 層在 [j, k] 區間搭積木的總方案數,dp 方程很顯然是 f[i][j][k] = f[i][j][k] + f[i - 1][x][y]; 其中 [j, k] 區間不存在不可放的位置,這是暴力 dp 的做法,時間複雜度為 $o(n^5)$。
字首和優化:
在上述圖示中,第 i - 1 層 f[i - 1][x][y] 即 [x, y] 這一部分很顯然可以用字首和優化掉,只用了 $o(1)$的時間複雜度即可完成,二維字首和初始化的公式為:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j],求解子矩陣為:s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1],不熟悉的可以畫圖推一下,比較容易理解。
時間複雜度為 $o(n^3)$,完全可以過。
#include usingnamespace
std;
typedef
long
long
ll;const
int n = 110, mod = 1e9 + 7
;int
n, m;
ll f[n][n][n];
ll s[n][n], c[n][n];
//字首和
void get_presum(int
i) }}//
子矩陣
int submatrix(int x1, int y1, int x2, int
y2)int
main()
} f[
0][1][m] = 1
; get_presum(0);
ll ans = 1
;
//dp 按行求解方案數
for (int i = 1; i <= n; ++i) }}
get_presum(i);
}cout
<< (ans + mod) % mod <
return0;
}
藍橋杯 搭積木
題目 小明最近喜歡搭數字積木,一共有10塊積木,每個積木上有乙個數字,0 9。搭積木規則 每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。最後搭成4層的金字塔形,必須用完所有的積木。下面是兩種合格的搭法 0 1 23 4 5 6 7 8 9 03 1 7 5 2 9 8 6 4請你計...
藍橋杯 搭積木
題目 搭積木 小明最近喜歡搭數字積木,一共有10塊積木,每個積木上有乙個數字,0 9。搭積木規則 每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。最後搭成4層的金字塔形,必須用完所有的積木。下面是兩種合格的搭法 0 1 2 3 4 5 6 7 8 9 0 3 1 7 5 2 9 8 ...
藍橋杯 搭積木
1.搭積木 問題描述 小明最近喜歡搭數字積木。一共有10塊積木,每個積木上有乙個數字,0 9。搭積木規則 每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。最後搭成4層的金字塔形,必須用完所有的積木。下面是兩種合格的搭法 01 2 3 4 5 6 7 8 9 03 1 7 5 2 9 ...