最大矩陣(簡單DP)

2022-05-01 04:33:09 字數 2145 閱讀 4469

見題:

很水的一題,資料範圍太小,字首和加爆搜就行.

#includeusing

namespace

std;

const

int maxn=110

;int ans=1

,m,n,sum[maxn][maxn];

inline

intread()

while

(isdigit(ch))

return x*ff;

}inline

void put(int

x)int

main()

}for(int len=2;len<=min(n,m);len++)}}

put(ans);

return0;

}

可是還是想寫正解,dp;

對於這類的二維dp,個人理解就是如果儲存的從起點到終點的狀態會被一些情況所中斷,就要只考慮最下角的點所儲存的點的狀態,例如此題,我們可以儲存以(i,j)為右下角的狀態,以f[i][j]儲存以(i,j)為最右下角的最大正方形邊長.狀態轉移怎麼樣呢?

這是我們我們可以輕易的想起二維的字首和:f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j],那這個能否用字首和處理呢,見下圖:

最右下的小矩陣代表(i,j)可以很清楚地看出由左邊的點,上邊的點,左上角的點三個點的最小矩陣構成以個完整的矩陣,即:if(a[i][j]==1) f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1;

這也提醒我們min的意義就是幾個狀態都具備的共同元素.

這一題就不能用暴力了,(n<=2600,m<=2600)只能想正解,和上一題一樣我們可以用f[i][j]一(i,j)儲存合法的吃到的最大的魚的個數.

接下來就考慮狀態怎麼轉移,我自己也是嗑了許多時間還沒做出來,於是就看了題解...

給出**:

#includeusing

namespace

std;

#define _ 0

const

int maxn=2600

;int

m,n,a[maxn][maxn],f[maxn][maxn],s1[maxn][maxn],s2[maxn][maxn],ans;

inline

intread()

while

(isdigit(ch))

return x*ff;

}inline

void put(int

x)int

main()

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

if(a[i][j])}}

memset(f,

0,sizeof

(f));

memset(s1,

0,sizeof

(s1));

memset(s2,

0,sizeof

(s2));

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

if(a[i][j])}}

put(ans);

return (0^_^0

);}

啟示我們可以直接從最優解的轉移推狀態轉移方程...

最大子矩陣 DP

time limit 10000ms memory limit 165888kb 64bit io format lld llu hysbz 1084 這裡有乙個n m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。注意 選出的k個子矩陣不能相互重疊。第一行為n,m,k 1 n 10...

最大子矩陣 dp

已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是1 1 子矩陣。比如,如下4 4的矩陣 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 的最大子矩陣是 9 2 4 1 1 8 這個子矩陣的大小是15。輸入是乙個n n的矩陣。輸入的第一行給出n...

最大子矩陣問題 dp

e acmer 題意 給你乙個矩陣,求它的所有元素和最大的子矩陣.分析 我們只知道一維的情況就是經典的最大子段和.然而維數達到二維就變的複雜了.我們觀察資料範圍500,易想到n3 的演算法也能過.純暴力是n4 的方法 然後可以通過列舉其中一維,dp最後一維的方法求出.處理列上的和為字首和,然後列舉列...