poj 1050(DP)

来源:互联网 发布:retrofit post json 编辑:程序博客网 时间:2024/06/06 17:49
http://poj.org/problem?id=1050

题意:给你一个n*n的矩阵,要求求最大矩阵和(矩阵和就是矩阵内所有数字和)


思路:从一维的开始吧,给你一段数字要求求出最大某段数字和,

比如:

8-7 9 -3 6 5 -2 1 -4

答案明显是 9 -3 6 5 和为17

dp[i]表示以a[i]结尾的最大数字和。

代码如下:

memset(dp,0,sizeof(dp));for(int i=0;i<n;i++){    if(dp[i-1]>=0)        dp[i]=dp[i-1]+a[i];    else        dp[i]=a[i];}


接下来思考二维的:
我们首先把二维的数据转换成一维的。
dp[i][j][k]表示从i行到j行以k列为结束的矩阵的最大数字和。
比如:

40 -2 -7 0-4 1 -4 19 2 -6 2-1 8 0 -2


比如开始i=1;j=3

第一步操作是把二维化作一维(把同一列的数字求和),那么从第1行到第3行就变成了:5 1 -17 3
化作一维的后再用一维的思路来找
代码:

#include<stdio.h>#include<string.h>#include<algorithm>#define Inf 1<<29using namespace std;int n;int a[110][110];int dp[110][110][110];int main(){    while(~scanf("%d",&n))    {        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            {                scanf("%d",&a[i][j]);            }        }        memset(dp,0,sizeof(dp));        int ans=0;        for(int i=0; i<n; i++)        {            for(int j=i+1; j<n; j++)            {                for(int k=0; k<n; k++)                {                    int x=0;                    for(int l=i; l<=j; l++)                        x+=a[k][l];                    if(dp[i][j][k-1]>=0)                        dp[i][j][k]=dp[i][j][k-1]+x;                    else                        dp[i][j][k]=x;                    ans=max(ans,dp[i][j][k]);                }            }        }        printf("%d\n",ans);    }    return 0;}


原创粉丝点击