演算法篇 二維動態規劃問題

2021-10-24 02:28:45 字數 1454 閱讀 9757

題目:

給定乙個nxm的矩陣a和乙個整數k,小hi希望你能求出其中最大(元素數目最多)的子矩陣,並且該子矩陣中所有元素的和不超過k。

input

第一行包含三個整數n、m和k。

以下n行每行包含m個整數,表示a。

對於40%的資料,1 <= n, m <= 10  

對於100%的資料,1 <= n, m <= 250 1 <= k <= 2147483647 1 <= aij <= 10000

output

滿足條件最大的子矩陣所包含的元素數目。如果沒有子矩陣滿足條件,輸出-1。

sample input

3 3 9

1 2 3

2 3 4

3 4 5

sample output

4
/*演算法設計思想:將二維動態規劃問題轉化為一維動態規劃問題。

1.定義:設row[x][y]:第x行中前y個數的和,則row[x][q]-row[x][p]:第x行中第p+1~第q個數的和,

行x~y列u~v的矩形的元素之和:

row[x][v]-row[x][u-1]+row[x+1][v]-row[x+1][u-1]+…+row[y][v]-row[y][u-1]

2.過程:先將列固定,只移動行,取行所有的情況,就相當於求最長子段和的一維動態規劃問題。

再取列所有的情況,將每一次一維動態規劃的結果作為二維動態規劃的一項。*/

#include

using namespace std;

int dp[255][255];//儲存各行對應位置元素和的矩陣

int a[255][255];//輸入矩陣

int ans=-1;

int n,m,k;

typedef long long  ll;

int main(){

// cout<<"input m,n,k:";

//system("pause");

cin>>m>>n>>k;

for(int i=1;i<=m;i++){//對每一行的對應位置求和。

dp[i][0]=0;

for(int j=1;j<=n;j++){

cin>>a[i][j];

dp[i][j]=dp[i][j-1]+a[i][j];

for(int i=1;ifor(int j=i;j//先固定列,之後對列進行遍歷。

ll aa=0;

for(int k=1,l=1;k<=n;k++){

//固定列之後移動行轉化為一維動態規劃問題

aa+=dp[k][j]-dp[k][i-1];

while(aa>k){

aa-=dp[l][j]-dp[l][i-1];

++l;

ans=max(ans,(j-i+1)*(k-l+1));

coutreturn 0;

參考文章:

二維陣列 動態規劃

簡要描述 給定乙個m行n列的矩陣 m n個格仔 每個格仔中放著一定數量的平安果。你從左上角的各自開始,只能向下或者向右走,目的地是右下角的格仔。每走過乙個格仔,就把格仔上的平安果都收集起來。求你最多能收集到多少平安果。注意 當經過乙個格仔時,需要一次性把格仔裡的平安果都拿走。1 n,m 50 每個格...

二維費用的揹包問題(動態規劃)

二維費用的揹包問題 有 n n 件物品和乙個容量是 v v 的揹包,揹包能承受的最大重量是 m m 每件物品只能用一次。體積是 v i vi 重量是 m i mi 價值是 w i wi 求解將哪些物品裝入揹包,可使物品總體積不超過揹包容量,總重量不超過揹包可承受的最大重量,且價值總和最大。輸出最大價...

二維動態陣列

之前都是寫的小程式,一直用的靜態陣列,也沒出現問題。可是,最近碰到大型程式和工程,這時就要用動態陣列了。因為靜態陣列時儲存在棧中的,而動態陣列儲存在堆中。計算機的棧只有1m大小,而堆可以理論上達到計算機記憶體大小,可見當大型工程資料量非常大時,必須使用動態陣列了。c 的動態陣列的建立和刪除要用到ne...