1. 程式人生 > >51Nod 1050 迴圈陣列最大子段和(dp)

51Nod 1050 迴圈陣列最大子段和(dp)



其實就是求迴圈陣列的最大欄位和

題意:給定一個長度為50000的陣列,求它的迴圈陣列的最大子段和。

分析:本題與普通的最大子段和問題不同的是,最大子段和可以是首尾相接的情況,即可以迴圈。那麼這個題目的最大子段和有兩種情況

    (1)正常陣列中間的某一段和最大。這個可以通過普通的最大子段和問題求出。

    (2)此陣列首尾相接的某一段和最大。這種情況是由於陣列中間某段和為負值,且絕對值很大導致的,那麼我們只需要把中間的和為負值且絕對值最大的這一段序列求出,用總的和減去它就行了。

     即,先對原陣列求最大子段和,得到ans1,然後把陣列中所有元素符號取反,再求最大子段和,得到ans2,

     原

陣列的所有元素和為ans,那麼最終答案就是max(ans1, ans + ans2)

程式碼:

<span style="font-size:24px;">#include"stdio.h"
#include"stdlib.h"
#define N 50001
int a[N];
int n;

long long Maxsum(int a[])
{
	int i;
	long long sum=0,max=0;
	for(i=0;i<n;i++)
	{
		if(sum<0)    sum=a[i];
		else         sum+=a[i];
		if(sum>max)  max=sum;
	}
   return max;
}
int main()
{
	int i,j;
	long long sum=0,ans1,ans2;
	long long result;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	ans1=Maxsum(a);
	for(i=0;i<n;i++)   //求最小欄位和絕對值 
	  a[i]=-a[i];
	ans2=Maxsum(a);
	result=ans1>sum+ans2?ans1:sum+ans2;
	printf("%lld\n",result);
	return 0;
}</span>

相關推薦

51Nod 1050 迴圈陣列大子dp

 其實就是求迴圈陣列的最大欄位和 題意:給定一個長度為50000的陣列,求它的迴圈陣列的最大子段和。 分析:本題與普通的最大子段和問題不同的是,最大子段和可以是首尾相接的情況,即可以迴圈。那麼

51nod 1094 迴圈陣列大子

解題思路:本問題跟之前和為k的連續區間解題演算法稍有不同: 1.該題連續區間的範圍是迴圈序列; 2.如果仍然使用上述演算法會超時。 解題方法: 對於迴圈序列,需要考慮兩種情況: 1.不考慮迴圈序列的情況下求出連續序列的最大值 2.若是最大值的產生情況是一部

51Nod1050 迴圈陣列大子動態規劃

這題區間是可以迴圈的,如果不迴圈的狀態轉移方程是 if(dp[i-1]>0)   dp[i]=dp[i-1]+a[i]; else   dp[i]=a[i]; 現在題目要求是可以迴圈,分為兩種情況: 1、沒有迴圈,找到了最大的子段。 2、迴圈了,找到了最大的子段。 第一

SP1043 GSS1 - Can you answer these queries I線段樹,區間大子靜態

有一種 nbsp 不用 端點 合並 表示 格式 space iostream 題目描述 給出了序列A[1],A[2],…,A[N]。 (a[i]≤15007,1≤N≤50000)。查詢定義如下: 查詢(x,y)=max{a[i]+a[i+1

51Nod 1051 - 大子矩陣DP

題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1051 【題目描述】 一個M*N的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。 例如:3×3的矩陣: -1 3

hdu 1081/poj 1050 大子矩陣dp

換成谷歌瀏覽器以後終於可以黏貼程式碼了,更新以後的markdown真心難用。。。 dp問題,先把給定的二維矩陣壓縮,變成一維矩陣,如此即可變成hdu1003,用動態規劃的思路求解即可 #include<iostream> #include<cm

大子矩陣---dp

題目描述 一個M*N的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。 例如:3*3的矩陣: -1 3 -1 2 -1 3 -3 1 2 和最大的子矩陣是: 3 -1 -1 3 1 2 Input 第1行:M和N,中間用

POJ-1050 動態規劃大子大子

1、最大子段 由於最大子段不可能以負數或負數段開頭,可以以此得到演算法 int max(int a[],int n) { int sum,maxsum; int i ; sum = maxsum = 0; for(i =

C++學習1大子多種解法

多少 問題: code namespace 數據 組成 amp using () 問題:給定由n個數(可能為負數)組成的序列a1,a2,a3,...,an,求該序列子段和的最大值。 第一種解法:(最容易考慮的方法,將所有的子段一一相加,然後比較) 1 #include&

codevs 3981 動態大子線段樹

輸入 typedef fault namespace 一行 scrip img sum spl 題目傳送門:codevs 3981 動態最大子段和 題目描述 Description 題目還是簡單一點好... 有n個數,a[1]到a[n]。 接下來q次查詢,每次動

51Nod 1052 - 大M子DP

題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1052 【題目描述】 N個整陣列成的序列a[1],a[2],a[3],…,a[n],將這N個數劃分為互不相交的M個子段,並且這M個子段的和是最大的。如果

求區間大子線段樹

填坑。。。 線段樹需要維護的是: 左端點 x 右端點 y (本人喜歡直接維護端點) [x,y]內的最大子段和 ms [x,y]的區間和 s [x,y]內的緊靠左端點的最大子段和 ls [x,y]內的緊靠右端點的最大子段和 rs 困難就是,upd

Max Sum Plus Plus 大子 經典 Dp

kuangbin專題連結:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68966#problem/A 題意:最大m子段問題:求給定無交叉的區間數目,求出最大和值。 看到,n達到1000000,心裡第一想法就是隻

大子DP算法設計與其單元測試

his 最大子數組 利用 來看 中一 tco public art 容器 表情包形象取自番劇《貓咪日常》 那我也整一個 曾幾何時,筆者是個對算法這個概念漠不關心的人,由衷地感覺它就是一種和奧數一樣華而不實的存在,即便不使用任何算法的思想我一樣能寫出能跑的程序 直到一年前

LeetCode_Python3: 53. 大子簡單

開始之前:從2018/8/27開始刷LeetCode,計劃每週刷五題,週末進行總結併發布在csdn上,計劃先刷150道題,從簡單開始。 week 3-3 要求: CODE: class Solution: def maxSubArray(self, num

Leetcode:大子java

給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。 進階: 如果你已經實現複雜度為 O(n) 的解法,嘗

51Nod 1050 循環數組大子 | DP

urn F12 int ges href 中間 art space style Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 分析: 有兩種可能,第一種為正常從[1 - n]序列中的最大子字段和;第二種為數組的total_sum -

51nod 1050 循環數組大子【環形DP/大子/正難則反】

pre 不但 spa 個數 ace lld 時間 lin bsp 1050 循環數組最大子段和 基準時間限制:1 秒 空間限制:131072 KB 分值: 10 難度:2級算法題 收藏 關註 N個整數組成的循環序列a[1],a[2

51nod 1049 大子

題目描述 N個整陣列成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的連續子段和的最大值。當所給的整數均為負數時和為0。 例如:-2,11,-4,13,-5,-2,和最大的子段為:11,-4,13。和為20。 輸

poj 1050 To the Max動態規劃處理二維大子

2、題目大意: 給一個N,然後給定一個N*N的二維陣列,然後求一個子矩陣,使得其中的數加起來和最大 3、思路: 將二維陣列轉換成一維陣列,假設二維陣列是M行N列,那麼將二維陣列分成N條,用dp[i]記錄第i列的和(可以是任意連續長度,for迴圈就能實現),那麼將dp[i]