2018藍橋杯B組決賽 E 搭積木

2022-06-01 13:42:09 字數 1423 閱讀 9491

題解

該題考察經典演算法,可我還是太菜了...,不會做/(ㄒ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 using

namespace

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 ...