nyoj - 44 子串和 + nyoj - 104 最大和
http://acm.nyist.net/JudgeOnline/problem.php?pid=44
http://acm.nyist.net/JudgeOnline/problem.php?pid=104
nyoj 44 字串和是经典的动态规划问题,104题将44题的一维最大和扩展到矩阵中,求子矩阵的最大和。
思路大体还是一致的,先来说nyoj44吧。最大字段和问题用枚举,分治和动态规划都能解决,时间复杂度分别为O(n^2), O(nlogn), O(n)。
dp的状态方程: b[j] = max{b[j-1] + a[j], a[j]}, 1<= j <= n; if b[j-1] >0, b[j] = b[j-1]+a[j];else b[j] = a[j];
int maxsum(int n, int *a)
{
int i;
int sum = 0, b = 0;
for(i = 0; i < n; i++)
{
if(b > 0)
b += a[i];
else b = a[i];
if(b > sum)
sum = b;
}
return sum;
}
nyoj 104是在二维矩阵上的子段和问题,大致思路和一维的一样
#include<iostream>
#include<cstdio>
using namespace std;
int ma[105][105];
int b[105];
int row, col;
int main()
{
int ncases, i, j, k, max, sum;
scanf("%d", &ncases);
while(ncases--)
{
scanf("%d%d", &row, &col);
sum = 0;
for(i = 0; i < row; i++)
for(j = 0; j < col; j++)
scanf("%d", &ma[i][j]);
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
b[j] = 0;
for(j = i; j < row; j++)
{
for(k = 0; k < col; k++)
b[k] += ma[j][k];
max = maxsum(col, b); //用的上边的maxsum(int n, int *a);
if(max > sum)
sum = max;
}
}
printf("%d\n", sum);
}
return 0;
}