您的位置:首页 > 其它

HDU1081:To The Max(最大子矩阵,线性DP)

2015-03-31 16:40 381 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1081

自己真够垃圾的,明明做过一维的这种题,但遇到二维的这种题目,竟然不会了,我也是服了(ps:猪啊)。

最终还是看了题解。

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n,w[110][110],t;
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(w,0,sizeof(w));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&t);
w[i][j]+=w[i][j-1]+t;
}
}
int maxx=-inf;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
int sum=0;
for(int k=1;k<=n;k++)
{
if(sum<0) sum=0;
sum+=w[k][j]-w[k][i-1];
if(sum>maxx)
maxx=sum;
}
}
}
printf("%d\n",maxx);
}
return 0;
}


大神的题解:

这一题就是将一维的最大字段和扩展到二维,在一维的求最大字段和的过程中是这样操作的:

int max_sum(int n)
{
int i, j, sum = 0, max = -10000;
for(i = 1; i <= n; i++)
{
if(sum < 0)
sum = 0;
sum += a[i];
if(sum > max)
max = sum;
}
return sum;
}


扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[i][j]从表示第i行第j个元素变成表示第i行前j个元素和,这样map[k][j]-map[k][i]就可以表示第k行从i->j列的元素和。只要比一维多两层循环枚举i和j就行了。


#include <iostream>
#define MAX 101
using namespace std;
int map[MAX][MAX];
int main()
{
int n, i, j, temp, k;

while(scanf("%d", &n) != EOF)
{
memset(map, 0, sizeof(map));
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d", &temp);
map[i][j] += map[i][j - 1] + temp;//这里表示第i行的前j列之和
}
int max = -100000;
for(i = 1; i <= n; i++)
for(j = i; j <= n; j++)
{
int sum = 0;
for(k = 1; k <= n; k++)
{
if(sum < 0)
sum = 0;
sum += map[k][j] - map[k][i  - 1];//这里表示前k行,i->j列之和
if(sum > max)
max = sum;
}
}
printf("%d\n", max);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: