HDU 1081 To The Max 动态规划

题目连接http://acm.hdu.edu.cn/showproblem.php?pid=1081

这道题一开始以为是一个搜索题,一提搜索我就想到什么dfs bfs等等,还有什么并查集一些还么接触过的东西,所以我刚开始的的时候直接放弃,这个也是比赛之后做的。

后来看了解题报告知道这是个动态规划。是那个我们比较熟悉的那个最大连续字段和问题的扩展。

原动态方程式    dp[i] = dp[i-1] > 0? dp[i-1] + a[i]:a[i];

以上是一维方程。而这道题无非是扩展到了二维;

所谓的二维矩阵的和,接就是一定行数的在n列中最大的和,也就是同列的相同行数的和的最大值。这个行数也就是可以使任意的两行间的数,即i-j行。

而以上的dp[i]是以第 i 个数结尾的最大的和,而在二维中可以是每 i-j 行中捆绑形式第k列结尾的最大的值。

同样还是遍历得到结果、

for(i = 1;i <= n;i++)

{

     for(j = i;j<= n;j++)

      {}

}

在{}中用一个

for(k = 1;k <= n;k++)

sum[k] += a[j][k];

来储存各行的和。

然后用dp算出即可

代码如下

View Code
#include<stdio.h>
#include<string.h>
int a[105][105];
int n,dp[105],sum[105];
int DP()
{
    int i;
    dp[1] = sum[1];
    int max;
    max = dp[1];
    for(i = 2;i <= n;i++)
    {
        if(dp[i-1] > 0)
            dp[i] = dp[i-1] + sum[i];
        else
            dp[i] = sum[i];
        if(max < dp[i])
            max = dp[i];
    }
    return max;
}
int main()
{
    int i,j,k,res,max;
    while(scanf("%d",&n) !=EOF)
    {
    for(i = 1;i <= n;i++)
        for(j = 1;j <= n;j++)
            scanf("%d",a[i]+j);
    res = 0;
    for(i = 1;i <= n;i++)
    {
        
        memset(sum,0,sizeof(sum));
        for(j = i;j <= n;j++)
        {
            for(k = 0;k <= n;k++)
                sum[k] += a[j][k];
            max = DP();
            if(res < max)
                res = max;
        }
    }
    printf("%d\n",res);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/0803yijia/p/2594086.html