基础算法学习2-dp
Posted panboo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础算法学习2-dp相关的知识,希望对你有一定的参考价值。
一、算法题: 最大子阵
给定一个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的主要内容,如果未能解决你的问题,请参考以下文章