1. 程式人生 > >基礎算法學習2-dp

基礎算法學習2-dp

cst tmp 兩個 思想 inf clu fff 一維數組 輸入格式

一、算法題: 最大子陣

  給定一個n×m 的矩陣 A,求A 中的一個非空子矩陣,使這個子矩陣中的元素和最大。其中,A 的子矩陣指在 A 中行和列均連續的一部分。
輸入格式
輸入的第一行包含兩個整數 n,m(1≤n,m≤50),分別表示矩陣 A 的行數和列數。
接下來 n 行,每行 m 個整數,表示矩陣 A(?1000≤i,j≤1000)。
輸出格式
輸出一行,包含一個整數,表示 A 中最大子矩陣的元素和。
樣例輸入
3 3
2 -4 1
-1 2 1
4 -2 2
樣例輸出
6

二、解題代碼:

 1 #include <iostream>
 2 using namespace std;
 3 int matrix[50
+5][50+5] = {0}; 4 const int inf = 0x7fffffff; 5 6 int get(int* dp, int m){ 7 int max = -inf; 8 int temp = 0; 9 for(int i=0;i<m;i++){ 10 temp=0; 11 for(int j=i;j<m;j++){ 12 temp += dp[j]; 13 if(temp>max){ 14 max = temp; 15 }
16 } 17 } 18 return max; 19 } 20 21 int main() { 22 int n = 0, m = 0; 23 cin >> n >> m; 24 for(int i = 0; i < n; i++){ 25 for(int j = 0; j < m; j++){ 26 cin>>matrix[i][j]; 27 } 28 } 29 int max = -inf; 30 for(int i=0
;i<n;i++){ 31 int dp[50+5] = {0}; 32 for(int j=i;j<n;j++){ 33 int k; 34 for(k=0;k<m;k++){ 35 dp[k] += matrix[j][k]; 36 } 37 int tmp = get(dp,k); 38 if(tmp>max){ 39 max = tmp; 40 } 41 } 42 } 43 cout << max; 44 return 0; 45 }

三、解題心得

  1、對於二維的矩陣數據,基本上要使用三層for循環才能將所有問題考慮進去,上一個問題的局部最優解是下一個局部問題的條件。

  2、對於get函數中,找到一維數組裏的最小矩陣和,if判斷要放在內層for循環裏面,要不然考慮的情況就不全面。

四、優化代碼

 1 #include<iostream> 
 2 #include <cstring> 
 3 
 4 using namespace std; 
 5 int max(int a,int b) { 
 6     return a>b?a:b;
 7 } 
 8 int main() { 
 9     int n,m,i,j,k,MAX=-9999,a[51][51],dp[51][51]; 
10     cin>>n>>m; memset(a,0,sizeof(a)); 
11     memset(dp,0,sizeof(dp)); 
12     for(i = 1; i <= n; ++i){
13         for(j = 1; j <= m; ++j){
14             cin>>a[i][j]; 
15             dp[i][j]=dp[i-1][j]+dp[i][j-1]+a[i][j]-dp[i-1][j-1]; 
16         } 
17     } 
18     
19     for(i=1;i<=n;++i){
20         for(j=1;j<=m;++j){
21             for(int p=1;p<=i;++p){
22                 for(int q=1;q<=j;++q){
23                     MAX =max(dp[i][j]-dp[i][q-1]-dp[p-1][j]+dp[p-1][q-1],MAX);
24                 }
25             }
26         }
27     }
28     cout<<MAX;
29     return 0;
30 }

解題心得:

  1、優化後的解法,dp思想更加明顯。重點就是 該的狀態轉換方程。

  

基礎算法學習2-dp