洛谷 P1437 HNOI2004 敲磚塊

2021-07-24 14:58:48 字數 1569 閱讀 6404

在乙個凹槽中放置了 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 52 2 3 4

8 2 7

2 349

輸出樣例#1:

19首先看到這道題後無從下手,覺得無論如何設計狀態都會有後效性,不能滿足動規條件。

考慮將三角形轉90度。變成: 4

3 72 2 3

2 8 2 49

這一行就可以由前一行的狀態轉移過來。

設f[i]j[k]表示一定選第i列前j個數,一共選了k個數的最大得分。

因為選乙個(i,j)數,一定將第i行的前j個數都取了,所以容易想到字首和優化。

f[i][j][k]=max(f[i-1][l][k-j]+s[i][j])(j-1=

注意i行可以不選,即j從零開始列舉,c黨注意判陣列是否越界。(這個很不容易像,會坑50分)

考慮優化:開g陣列表示f的倒序最大值,就不用列舉l了,少一重迴圈,會快很多,初始化較繁瑣。

未優化:

#include#include#include#includeusing namespace std;

const int n=55;

int n,m,ans,a[n][n],c[n][n],s[n][n],f[n][n][n*(n+1)/2];

int main()

優化後:

#include#include#include#includeusing namespace std;

const int n=55;

int n,m,ans,a[n][n],c[n][n],s[n][n],f[n][n][n*(n+1)/2],g[n][n][n*(n+1)/2];

int main()

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

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

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

printf("%d\n",ans);

return 0;

}

dp 洛谷P1437 HNOI2004 敲磚塊

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

洛谷P1437 HNOI2004 敲磚塊 dp

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

洛谷 P2292 HNOI2004 L語言

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