ACPC I.Omar Loves Candies


Omar Loves Candies
Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:65536KB
Total submit users: 42, Accepted users: 33
Problem 12830 : No special judgement
Problem description

Omar loves to eat a lot of candies, but unfortunately most of the candies are not healthy. So his parents found a way to give each candy a score, a higher score means a healthier candy (the score is an integer that can be positive, zero or negative).
One day he went with his parents to buy some candies, and they found a strange store where all the candies are stored in a 2-dimensional grid of N rows with M candies in each row. The rows are numbered from 1 to N from top to bottom, and the columns are numbered from 1 to M from left to right and every cell contains one candy.
They noticed something else, any candy (except for those in the first row) is healthier than the candy which is exactly above it, and any candy (except for those in the first column) is healthier than the candy which is exactly to its left (healthier means having higher score as defined above).
There is one more strange thing about this store, to buy some candies you have to select a sub-rectangle of the candies’ grid and buy all the candies within this sub-rectangle.
Omar’s parents want to select a non-empty sub-rectangle that has the maximum sum of candies’ scores among all possible sub-rectangles.
For example, consider the grid in the example input. Some of the possible sub-rectangles of candies they can select are [-2, -1, 2, 3], [-4, -2, -1] or [2, 3, 4, 5]. The last sub-rectangle has the maximum sum of scores, which is 14. They can not select the following lists of candies [1, 2, 3, 4, 5] or [-2, -1, 2] (because these lists do not form a sub-rectangle of the given grid).

Can you help them by writing a program which finds the non-empty sub-rectangle with the maximum possible sum of scores in the given grid?


Input

Your program will be tested on one or more test cases. The first line of the input will be a single integer T, the number of test cases T ranges in(1,100). Followed by the test cases, each test case starts with a line containing two integers separated by a single space N M (N,M ranges in(1,1,000)) representing the dimensions of the candies’ grid, followed by N lines, each one contains M integers separated by a single space, representing the candies’ scores in this row. The given grid representation will satisfy the conditions mentioned above, and each integer in the grid will not be less than -2,000 and will not be greater than 2,000.


Output

For each test case, print a single line which contains a single integer representing the maximum sum of scores they can get from a non-empty sub-rectangle.


Sample Input
1
3 3
-4 -2 -1
-3 2 3
1 4 5
Sample Output
14
Problem Source
ACPC 2013
Submit   Discuss   Judge Status  Problems  Ranklist 

想法:1.现将原数组转180度(就是让上面的一定比下面大,左边的一定的比右边大,和题意反过来,便于处理)

    2.从上到下进行处理,对于dp[i][j] 有 dp[i][j-1] + col[i][j] 或者dp[i-1][j] + row[i][j],取最大值(其实不算个dp,我也没想明白)

   一开始WA,由于从2开始处理,忘了处理只有一行或者一列的情况,代码如下(风格有点丑......):


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int init[1100][1100];
int matrix[1100][1100];
int row[1100][1100];
int col[1100][1100];
int dp[1100][1100];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(init,0,sizeof(init));
        memset(matrix,0,sizeof(matrix));
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        memset(dp,0,sizeof(dp));
        int n,m;
        int i,j;
        scanf("%d%d",&n,&m);
        for(i = 1;i <= n;i++)
        {
            for(j = 1;j <= m;j++)
            {
                scanf("%d",&matrix[i][j]);
            }
        }
        for(i = n;i >= 1;i--)
        {
            for(j = m;j >= 1;j--)
            {
                init[n-i+1][m-j+1] = matrix[i][j];
            }
        }//翻转
        for(i = 1;i <= n;i++)
        {
            for(j = 1;j <= m;j++)
            {
                row[i][j] = init[i][j];
                col[i][j] = init[i][j];
            }
        }//赋值
        for(i = 1;i <= n;i++)
        {
            for(j = 1;j <= m;j++)
            {
                row[i][j]+=row[i][j-1];
                col[j][i]+=col[j-1][i];
            }
        }//计算行列
        dp[1][1] = init[1][1];
        int max_sum = dp[1][1];
        for(i = 2;i <= m;i++)
        {
            dp[1][i] = dp[1][i-1]+col[1][i];
            if(dp[1][i] > max_sum)
                max_sum = dp[1][i];
        }
        for(i = 2;i <= n;i++)
        {
            dp[i][1] = dp[i-1][1]+row[i][1];
            if(dp[i][1] > max_sum)
                max_sum = dp[1][i];
        }
        for(i = 2;i <= n;i++)
        {
            for(j = 2;j <= m;j++)
            {
                dp[i][j] = max(dp[i][j-1]+col[i][j],dp[i-1][j]+row[i][j]);
                if(dp[i][j] > max_sum)
                    max_sum = dp[i][j];
            }
        }
        printf("%d\n",max_sum);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值