UVa 10827:Maximum sum on a torus

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1768

原题:

A grid that wraps both horizontally and vertically is called a torus. Given a torus where each cell contains an integer, determine the sub-rectangle with the largest sum. The sum of a sub-rectangle is the sum of all the elements in that rectangle. The grid below shows a torus where the maximum sub-rectangle has been shaded.

1 -1 0 0 -4
2 3 -2 -3 2
4 1 -1 5 0
3 -2 1 -3 2
-3 2 4 1 -4

Input

The first line in the input contains the number of test cases (at most 18). Each case starts with an integer N (1≤N≤75) specifying the size of the torus (always square). Then follows N lines describing the torus, each line containing N integers between -100 and 100, inclusive.

Output

For each test case, output a line containing a single integer: the maximum sum of a sub-rectangle within the torus.

样例输入:

2

5

1 -1 0 0 -4

2 3 -2 -3 2

4 1 -1 5 0

3 -2 1 -3 2

-3 2 4 1 -4

3

1 2 3

4 5 6

7 8 9

样例输出:

15

45

思路与总结:

是上一题(UVa 108 - Maximum Sum)的再次升级版。情况变复杂了很多。这个矩阵是可以“循环转动”的。例如,当所有行都上升一行,那么第一行就会变成最后一行(原先第2行变成第1行,第3行变成第2行……), 当所有行下降一行,最后一行就变成第一行。  同理,列也是循环的,把上一句话的所有“行“字变成”列“字就是列循环的情况。

怎样处理这种情况呢?

如果之前做过什么涉及到圆环啊之类的题目,那么肯定马上会想到把在原数组后面再增加重复一遍这个数列的数。 例如1,2,3,4,  处理后变成1,2,3,4,1,2,3。  那么这个新序列就可以枚举圆环出所有的连续序列。

同理,这题需要扩大增加这个矩阵, 把这个存这个矩阵数字的数组的每一行增加一倍, 重复一遍数字, 每一列也增加一倍重复一遍。最后形成一个新的2N*2N的大矩阵。

然后再在这个新的大矩阵中找到尺寸小于等于N*N的子矩阵的最大和。

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

由于增加了一个限制:子矩阵的尺寸要小于等于N*N, 那么在进行求“最大连续和”的过程时, 要进行线性扫描,这里需要用到单调队列的应用(以前做过一道单调队列求最大连续和长度有限制的题:Max Sum of Max-K-sub-sequence)。单调队列的用处就是维护一个长度小于N的最小值。

代码:

/*
 * UVa: 10827 - Maximum sum on a torus
 * Time: 0.236s
 * Author: D_Double
 */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 250
using namespace std;  

struct Node{
    int val; // 值
    int no;  // 下标
};  

int arr[MAXN][MAXN], sum[MAXN][MAXN], N, ans;  

inline void input(){
    memset(arr, 0, sizeof(arr));
    memset(sum, 0, sizeof(sum));
    for(int i=1; i<=N; ++i){
        for(int j=1; j<=N; ++j)
            scanf("%d", &arr[i][j]);
        for(int j=N+1; j<2*N; ++j)
            arr[i][j]=arr[i][j-N];
    }
    for(int i=N+1; i<2*N; ++i){
        for(int j=1; j<2*N; ++j)
            arr[i][j] = arr[i-N][j];
    }
    // 转化
    for(int i=1; i<2*N; ++i){
        for(int j=1; j<2*N; ++j)
            sum[i][j] = arr[i][j]+sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
    }
}  

inline void solve(){
    deque<Node>que;
    Node temp;
    int maxSum=-2147483646;  

    for(int i=1; i<2*N; ++i){
        for(int j=(i-N>=0?i-N:0) ; j<i; ++j){ // 枚举
            que.clear(); // 记住要清空!!
            int prev=0;
            for(int k=1; k<2*N; ++k){
                // 维护单调队列
                while(!que.empty() && que.back().val > prev)
                    que.pop_back();
                while(!que.empty() && que.front().no < k-N)
                    que.pop_front();
                temp.val=prev, temp.no=k-1;
                que.push_back(temp);  

                int val=sum[i][k]-sum[j][k]-que.front().val;  

                if(val>maxSum) maxSum=val;
                prev = sum[i][k]-sum[j][k];
            }
        }
    }
    printf("%d\n", maxSum);
}  

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        input();
        solve();
    }
}

作者:csdn博客 shuangde800

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索矩阵
, include
, 队列
, sum
, 1768
, The
, 一行
, 最大子矩阵
, 单调队列
求小于n
sensuva on好用吗、sensuva on、torus、nottorus、3d torus,以便于您获取更多的相关知识。

时间: 2024-11-08 20:24:26

UVa 10827:Maximum sum on a torus的相关文章

UVa 108:Maximum Sum

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=44 原题: Background A problem that is simple to solve in one dimension is often much more difficult to solve in more than one dim

UVa 10656 Maximum Sum (II) (water ver.)

10656 - Maximum Sum (II) Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1597 In a given a sequence of non-negative integers you will have to find such a

UVa 507:Jill Rides Again

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=448 类型: 最大连续和 原题: Jill likes to ride her bicycle, but since the pretty city of Greenhills where she lives has grown, Jill oft

UVa 714:Copying Books,最大值最小化问题(贪心 + 二分)

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most fa

UVa 10700:Camel trading

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1641 原题: Background Aroud 800 A.D., El Mamum, Calif of Baghdad was presented the formula 1+2*3*4+5, which had its origin in the

UVa 757:Gone Fishing

[题目链接] http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=698 [原题]John is going on a fishing trip. He has h hours available ( ), and there are n lakes in the area ( ) all reachable a

UVa 639:Don&#039;t Get Rooked, 类八皇后问题

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=580 题目类型: 暴力, 回溯法 题目: In chess, the rook is a piece that can move any number of squares vertically or horizontally. In this p

UVa 301:Transportation

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=237 题目类型: 回溯法 原题: Ruratania is just entering capitalism and is establishing new enterprising activities in many fields includ

UVa 10341: Solve It

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1282 原题: Solve the equation:        p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0        where 0 <= x <= 1. Input