• UPC3463: Maximal-sum Subsequence


    题目描述

    给一个 N×N 的矩阵 M,可以取连续的一段数(必须是横着或者竖着或者斜着,这个矩阵是循环的,具体如下)。要求找到一个子序列,使得这个序列的和最大。

    对于 N=8 的矩阵,如下序列都是合法的:
        M2,1,M2,2,M2,3,M2,4,M2,5,M2,6,M2,7,M2,8.
        M2,2,M2,3,M2,4.
        M2,6,M2,7,M2,8,M2,1,M2,2.
        M4,3,M5,3,M6,3,M7,3.
        M1,2,M2,3,M3,4,M4,5.
        M2,4,M3,3,M4,2,M5,1.
        M3,3,M4,2,M5,1,M1,5.
        M5,6.
    一个元素不可取多次,取的必须是连续的一段。
    可以什么都不取(即答案为 0)。
     

    输入

    第一行一个数 T (T≤30),表示数据组数。
    每一组数据第一行为一个正整数 N (1≤N≤1000)。
    接下来 N 行每行 N 个数表示这个矩阵。(每个元素大小在 −32768 到 32767 之间)

    输出

    每组数据一行表示最大的序列和。

    样例输入

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

    样例输出

    24
    

    提示

    样例解释:选取序列 M3,4,M4,3,M1,2。

     
    循环数组最大子串和=max(数组和+元素取反后最大子串和,原数组最大子串和)
    然后对横、竖、从左上到右下,从左下到右上的所有结果取最大值
     
    #include "bits/stdc++.h"
    
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 1100;
    int a[maxn][maxn], b[maxn][maxn];
    int n;
    int f1[maxn], f2[maxn];
    int ans;
    
    int main() {
        freopen("input.txt", "r", stdin);
        int _;
        scanf("%d", &_);
        while (_--) {
            scanf("%d", &n);
            ans = -inf;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    scanf("%d", &a[i][j]);
                    b[i][j] = -a[i][j];
                }
            }
            int sum, max1, max2;
            for (int i = 1; i <= n; i++) {
                sum = 0, max1 = -inf, max2 = -inf;//max2为取反后最大子串和
                for (int j = 1; j <= n; j++) {
                    sum += a[i][j];
                    f1[j] = 0;
                    f2[j] = 0;
                }
                for (int j = 1; j <= n; j++) {
                    if (f1[j - 1] >= 0) {
                        f1[j] = f1[j - 1] + a[i][j];
                    } else
                        f1[j] = a[i][j];
                    if (f2[j - 1] >= 0) {
                        f2[j] = f2[j - 1] + b[i][j];
                    } else f2[j] = b[i][j];
                    max1 = max(max1, f1[j]);
                    max2 = max(max2, f2[j]);
    
                }
                ans = max(ans, max(sum + max2, max1));
    
                sum = 0, max1 = -inf, max2 = -inf;
                for (int j = 1; j <= n; j++) {
                    sum += a[j][i];
                    f1[j] = 0;
                    f2[j] = 0;
                }
                for (int j = 1; j <= n; j++) {
                    if (f1[j - 1] >= 0) {
                        f1[j] = f1[j - 1] + a[j][i];
                    } else
                        f1[j] = a[j][i];
                    if (f2[j - 1] >= 0) {
                        f2[j] = f2[j - 1] + b[j][i];
                    } else
                        f2[j] = b[j][i];
                    max1 = max(max1, f1[j]);
                    max2 = max(max2, f2[j]);
                }
                ans = max(ans, max(sum + max2, max1));
    
                sum = 0, max1 = -inf, max2 = -inf;
                for (int j = 1; j <= n; j++) {
                    sum += a[j][(j + i - 1) % n + 1];
                    f1[j] = 0;
                    f2[j] = 0;
                }
                for (int j = 1; j <= n; j++) {
                    if (f1[j - 1] >= 0) {
                        f1[j] = f1[j - 1] + a[j][(j + i - 1) % n + 1];
                    } else
                        f1[j] = a[j][(j + i - 1) % n + 1];
                    if (f2[j - 1] >= 0) {
                        f2[j] = f2[j - 1] + b[j][(j + i - 1) % n + 1];
                    } else
                        f2[j] = b[j][(j + i - 1) % n + 1];
                    max1 = max(max1, f1[j]);
                    max2 = max(max2, f2[j]);
                }
                ans = max(ans, max(sum + max2, max1));
    
                sum = 0, max1 = -inf, max2 = -inf;
                int t;
    
                for (int j = 1; j <= n; j++) {
                    t = (n - j - 1 + n) % n + 1;
                    sum += a[t][(j - i - 1 + n) % n + 1];
                    f1[j] = 0;
                    f2[j] = 0;
                }
                for (int j = 1; j <= n; j++) {
                    t = (n - j - 1 + n) % n + 1;
                    if (f1[j - 1] >= 0) {
                        f1[j] = f1[j - 1] + a[t][(j - i - 1 + n) % n + 1];
                    } else
                        f1[j] = a[t][(j - i - 1 + n) % n + 1];
                    if (f2[j - 1] >= 0) {
                        f2[j] = f2[j - 1] + b[t][(j - i - 1 + n) % n + 1];
                    } else
                        f2[j] = b[t][(j - i - 1 + n) % n + 1];
                    max1 = max(max1, f1[j]);
                    max2 = max(max2, f2[j]);
                }
                ans = max(ans, max(sum + max2, max1));
            }
    
            if (ans < 0) ans = 0;
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Extjs combobox
    Extjs中全键盘操作,回车跳到下一单元格
    MVC调试时遇到的URL问题
    不用插件 让Firefox 支持网页翻译
    aspNet各种模块介绍
    IntelliJ IDEA 激活
    The method getTextContent() is undefined for the type Node 错误解决
    svn服务器地址变更,客户端更改服务器地址方法
    IntelliJ IDEA中TortoiseSVN修改服务器地址的方法
    修改MyEclipse中的SVN地址
  • 原文地址:https://www.cnblogs.com/albert-biu/p/10339716.html
Copyright © 2020-2023  润新知