洛谷P1437 HNOI2004 敲磚塊 dp

2022-04-30 05:54:09 字數 1489 閱讀 4574

在乙個凹槽中放置了 n 層磚塊、最上面的一層有n 塊磚,從上到下每層依次減少一塊磚。每塊磚

都有乙個分值,敲掉這塊磚就能得到相應的分值,如下圖所示。

14 15  4  3  23

33 33 76 2

2 13 11

22 23

31

如果你想敲掉第 i 層的第j 塊磚的話,若i=1,你可以直接敲掉它;若i>1,則你必須先敲掉第

i-1 層的第j 和第j+1 塊磚。

你現在可以敲掉最多 m 塊磚,求得分最多能有多少。

輸入格式:

輸入檔案的第一行為兩個正整數 n 和m;接下來n 行,描述這n 層磚塊上的分值a[i][j],滿足

0≤a[i][j]≤100。

對於 100%的資料,滿足1≤n≤50,1≤m≤n*(n+1)/2;

輸出格式:

輸出檔案僅一行為乙個正整數,表示被敲掉磚塊的最大價值總和。

輸入樣例#1: 複製

4 5

2 2 3 4

8 2 7

2 349

輸出樣例#1: 複製

19

非常妙的一道題目

首先我們最先想到的肯定是$f[i][j][k]$表示第$i$行第$j$列選了$k$個的最大價值

但是這樣由於第一行的緣故是有後效性的

轉換一下思路,用$f[i][j][k]$表示第$i$列,第$i$個,選了$k$

轉移的時候倒著列舉列,這樣就不會有後效性了

#include#include

#include

#include

#include

//#define int long long

using

namespace

std;

const

int maxn = 1e5 + 10, inf = 1e9 + 10

;inline

intread()

while(c >= '

0' && c <= '

9') x = x * 10 + c - '

0', c =getchar();

return x *f;

}int n, m, f[51][51][5001], a[5001][5001

]; main()

}int ans = 0

;

for(int i = 1; i <= n; i++)

for(int j = 1; j <= n - i + 1; j++)

ans =max(ans, f[i][j][m]);

printf("%d

", ans);

return0;

}

洛谷 P1437 HNOI2004 敲磚塊

在乙個凹槽中放置了 n 層磚塊 最上面的一層有n 塊磚,從上到下每層依次減少一塊磚。每塊磚 都有乙個分值,敲掉這塊磚就能得到相應的分值,如下圖所示。14 15 4 3 23 33 33 76 2 2 13 11 22 23 31如果你想敲掉第 i 層的第j 塊磚的話,若i 1,你可以直接敲掉它 若i...

dp 洛谷P1437 HNOI2004 敲磚塊

這道題不可以直接行列dp 這樣乙個狀態可以從非常多且複雜的狀態更新過來 很麻煩,不可取 標算 這裡講的很好 但是我們不用旋轉三角形,直接在dp的時候換一下順序就好啦 include include include include define ll long long using namespace...

洛谷 P2292 HNOI2004 L語言

ac自動機 dp 洛谷這題資料加強之後用bfs t了最後一兩個點 用了乙個dp陣列做轉移 注意一下字串下標的偏移 因為有了dp陣列 存下trie樹上的結尾結點的字串長度 注意一下ac自動機的空間和dp陣列的空間 其他就沒啥了 include include include include inclu...