【循环数组的最大字串和】Maximal-sum Subsequence
【循环数组的最大字串和】Maximal-sum Subsequence
PROBLEM
题目描述
给一个 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. (按样例理解是M8,6 ,emmmmm)
    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。
SOLUTION
题面好像有点问题,应该按照提示(样例)来理解。
首先你要会如何求数组的最大字串和。
然后循环数组最大字串和 = max(数组求和+数组元素取反后的最大字串和,原数组的最大字串和)
最后每行每列以及所有斜向上的答案取最值即可。
CODE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2005;
int martix[MAXN][MAXN];
int dp[MAXN];
int py(int x,int n){
    while (x<0)x+=n;
    while (x>=n)x-=n;
    return x;
}
int cal(int arr[],int n) {
    int sum = 0;
    memset(dp, 0, sizeof(dp));
    sum = dp[0] = arr[0];
    for (int i = 1; i < n; i++) {
        dp[i] = max(arr[i], dp[i-1]+arr[i]);
        sum += arr[i];
    }
    int ans = 0;
    for (int i = 1; i < n; i++) {
        if (dp[i] > dp[ans]) {
            ans = i;
        }
    }
    int ans1 =  dp[ans];
    for (int i = 0; i < n; i++) {
        arr[i] = -arr[i];
    }
    memset(dp, 0, sizeof(dp));
    dp[0] = arr[0];
    for (int i = 1; i < n; i++) {
        dp[i] = max(arr[i], dp[i-1]+arr[i]);
    }
    ans = 0;
    for (int i = 1; i < n; i++) {
        if (dp[i] > dp[ans]) {
            ans = i;
        }
    }
    int ans2 = dp[ans];
    return max(ans1,ans2+sum);
}
int main(){
    int T;
    for(scanf("%d",&T);T;T--){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%d",&martix[i][j]);
            }
        }
        int ans = 0;
        for(int i=0;i<n;i++){
            int carry[MAXN];
            for(int j=0;j<n;j++){
                carry[j] = martix[i][j];
            }
            ans = max(ans,cal(carry,n));
            for(int j=0;j<n;j++){
                carry[j] = martix[j][i];
            }
            ans = max(ans,cal(carry,n));
            for(int j=0;j<n;j++){
                carry[j] = martix[py(i-j,n)][py(j,n)];
            }
            ans = max(ans,cal(carry,n));
            for(int j=0;j<n;j++){
                carry[j] = martix[py(i-j,n)][py(n-j-1,n)];
            }
            ans = max(ans,cal(carry,n));
        }
        cout<<ans<<endl;
    }
}
												
											【循环数组的最大字串和】Maximal-sum Subsequence的更多相关文章
- 1042 数字0-9的数量    1050 循环数组最大子段和    1062 序列中最大的数    1067 Bash游戏 V2    1092 回文字符串
		
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次 ...
 - 前端开发:setTimeout与setInterval 定时器与异步循环数组
		
前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ...
 - lintcode循环数组之连续子数组求和
		
v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. ...
 - 51nod 1050 循环数组最大子段和
		
题目链接:51nod 1050 循环数组最大子段和 #include<stdio.h> #include<algorithm> using namespace std; ; l ...
 - 深入理解循环队列----循环数组实现ArrayDeque
		
我们知道队列这种数据结构的物理实现方式主要还是两种,一种是链队列(自定义节点类),另一种则是使用数组实现,两者各有优势.此处我们将要介绍的循环队列其实是队列的一种具体实现,由于一般的数组实现的队列结构 ...
 - shell 循环数组
		
循环数组 ;i<${#o[*]};i++)) do echo ${o[$i]} done
 - 整理JavaScript循环数组和对象的方法
		
众所周知,常用的循环语句有for.while.do-while.for-in,forEach以及jQuery中提供的循环的方法:以及ES6中提供的很多用来循环对象的方法如map, 在 Javascri ...
 - CodeForces 598B(循环数组)
		
对于循环数组的问题,就是找偏移K后位置 偏移后位置=起始位置+(相对位置+K)%(长度+1) #include <iostream> #include <string> #in ...
 - 51Nod 1050 循环数组最大子段和 | DP
		
Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 分析: 有两种可能,第一种为正常从[1 - n]序列中的最大子字段和:第二种为数组的total_sum - ([1-n] ...
 
随机推荐
- SSH框架之Hibernate《一》
			
hibernate的基础入门 一:hibernate和ORM的概念部分 1.1hibernate概述: Hibernate框架是当今主流的Java持久层框架之一 ...
 - js检测移动设备并跳转到相关适应页面。
			
PS:网页自适应的方式有多种.有通过CSS样式表来实现自适应(主流),也有通过显示不同的页面来实现的方式. 下面代码是记录通过判断设备特征来跳转到相关的页面的方法. 实现要求: 当手机,平板访问 a. ...
 - Linux文件权限命令及配置
			
http://www.cnblogs.com/CgenJ/archive/2011/07/28/2119454.html
 - BIO 和 NIO
			
一.阻塞(Block)和非阻塞(NonBlock) 阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候阻塞: 阻塞:往往需要等待缞冲区中的数据准备好过后才处理其他 ...
 - CF1119A Ilya and a Colorful Walk
			
题目地址:CF1119A Ilya and a Colorful Walk \(O(n^2)\) 肯定过不掉 记 \(p_i\) 为从下标 \(1\) 开始连续出现 \(i\) 的个数 那么对于每一个 ...
 - 萌新的IDEA_web开发笔记(未完)
			
萌新IDEA_web开发笔记 按兴趣自己搞的网页: http://47.94.140.98:8080/ow_web/my_web/web/ 暂时还没做完. 部署在租的服务器上面,背景视频加载可能有点慢 ...
 - k64 datasheet学习笔记26--Oscillator (OSC)
			
1.前言 OSC模块是一个晶体振荡器. 该模块使用晶体或谐振器与外部连接,为MCU产生一个参考时钟. 主要为下图红色框住的部分 2.特性和模式 Supports 32 kHz crystals (Lo ...
 - fiddler抓包工具
			
转载: http://www.cr173.com/html/15341_1.html https://www.cnblogs.com/shihaiming/p/5887654.html 软件简介: 数 ...
 - Exif格式分析
			
转载链接: http://blog.csdn.net/simonhehe/article/details/8593354 http://blog.csdn.net/lsiyun/article/det ...
 - pl/sql学习(5): 触发器trigger/事务和锁
			
(一)触发器简单介绍 触发器是由数据库的特定时间来触发的, 特定事件主要包括以下几种类型: (1)DML: insert, update,delete 增删改 (2)DDL: create, alte ...