代码改变世界

基础算法学习2-dp

2018-12-06 00:03  潘博  阅读(152)  评论(1编辑  收藏  举报

一、算法题: 最大子阵

  给定一个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思想更加明显。重点就是 该的状态转换方程。