hdu1081求最大子矩阵的和,DP

来源:互联网 发布:中国同性题材网络剧 编辑:程序博客网 时间:2024/06/14 18:34

思路:对于n行n列的矩阵求最大子矩阵和,则子矩阵必定是第i列到第j列,第a行到第b行,如果把每一行第i列到第j列的值计算好和作为一个值(即把这几列的数压缩成一个数),不就变成求前n行的子序列的最大和,就和hdu1003一样了http://acm.hdu.edu.cn/showproblem.php?pid=1003//或者压缩行,求前n列的最大子序列和。


代码:

压缩列:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 999999999using namespace std;const int MAX=101;int s[MAX][MAX];int main(){int n,m;while(cin>>n){for(int i=0;i<n;++i){for(int j=0;j<n;++j)scanf("%d",&s[i][j]);}int sum=0,Max=-INF,num;for(int i=0;i<n;++i){for(int j=i;j<n;++j){sum=0;for(int k=0;k<n;++k){//求前k行第i列到第j列的子矩阵的最大和 num=0;for(int a=i;a<=j;++a)num+=s[k][a];//求第k行第i列到第j列的值 sum=sum+num>num ? sum+num : num;Max=sum>Max ? sum : Max;}}}cout<<Max<<endl;}return 0;}
压缩行:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 999999999using namespace std;const int MAX=101;int s[MAX][MAX];int main(){int n,m;while(cin>>n){for(int i=0;i<n;++i){for(int j=0;j<n;++j)scanf("%d",&s[i][j]);}int sum=0,Max=-INF,num;for(int i=0;i<n;++i){for(int j=i;j<n;++j){sum=0;for(int k=0;k<n;++k){num=0;for(int a=i;a<=j;++a)num+=s[a][k];sum=sum+num>num ? sum+num : num;Max=sum>Max ? sum : Max;}}}cout<<Max<<endl;}return 0;}
在输入的时候就压缩矩阵(此处是压缩列),效率更高:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX=101;int sum[MAX][MAX];int main(){int n,a;while(cin>>n){for(int i=0;i<n;++i){for(int j=1;j<=n;++j){scanf("%d",&a);sum[i][j]=sum[i][j-1]+a;}}int num=0,Max=-INF;for(int i=0;i<n;++i){for(int j=i+1;j<=n;++j){num=0;for(int k=0;k<n;++k){num=num+sum[k][j]-sum[k][i]>sum[k][j]-sum[k][i] ? num+sum[k][j]-sum[k][i] : sum[k][j]-sum[k][i];Max=num>Max ? num : Max;}}}cout<<Max<<endl;}return 0;}




原创粉丝点击