NYOJ-104-最大和(DP)

来源:互联网 发布:搞笑p图软件 编辑:程序博客网 时间:2024/04/30 13:08

最大和
时间限制:1000 ms | 内存限制:65535 KB
难度:5
描述
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩阵为:

9 2
-4 1
-1 8
其元素总和为15。

输入
第一行输入一个整数n(0<n<=100),表示有n组测试数据;
每组测试数据:
第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
随后有r行,每行有c个整数;
输出
输出矩阵的最大子矩阵的元素之和。
样例输入
1
4 4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
样例输出
15

就是HDU-1081的翻版,坑点在于给的数值可能很小很小,最终结果要初始化为负无穷,就因为这个错了两把

代码

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>using namespace std;//二维最大字段和const int maxn=105;const int INF=0x3f3f3f3f;int num[maxn][maxn];int flag[maxn];int DP[maxn];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int N,M;        scanf("%d%d",&N,&M);        memset(num,0,sizeof(num));        for(int i=1; i<=N; i++)        {            for(int j=1; j<=M; j++)            {                int a;                scanf("%d",&a);                num[i][j]=num[i-1][j]+a;            }        }        int result=-INF;        for(int i=0; i<=N; i++)        {            for(int j=i+1; j<=N; j++)            {                memset(flag,0,sizeof(flag));                for(int k=1; k<=M; k++)                    flag[k]=num[j][k]-num[i][k];                memset(DP,0,sizeof(DP));                for(int k=1; k<=M; k++)                {                    DP[k]=max(DP[k-1]+flag[k],flag[k]);                    result=max(result,DP[k]);                }            }        }        printf("%d\n",result);    }    return 0;}
0 0
原创粉丝点击