這道題是簡單的dp例題拓展,問題是:給定一行數字,然後求這行數字中兩個連續子串行和的最大值,並輸出(兩個子串行不能有重疊的部分);
由於是初學者,可能想法比較侷限。我的總體思路是這樣:這題肯定和最大求子序列有關,然後進行工作:用dp1[i]表示以第i個數結尾的最大子串行的和,用dp[i]表示已第i個數為起點的最大子串行的和;這樣對於兩個子串行和的最大值,把n分成2部分,[0-j],(j,n)在這兩部分分別求dp1[i]得最大值和dp2[i]的最大值。這樣的話,所取到的兩個子串行一定不會有重合部分;
如何dp1[i],dp2[i]的最大值都[0,j],(j,n)這樣的區間算的話,時間複雜度就是o(n^2),這樣,我提交了試了一下,結果是tlo;然後我優化了一下:用陣列max1[i]表示前i個數中dp1[j]的最大值,max2[i]表示後(i,n)中dp2[j]的最大值;
這樣時間複雜度變為o(n),是不會超時的。下面是**:
#include
#include
using namespace std;
int a[60000];
int dp1[60000],dp2[60000],max1[60000],max2[60000];
int main()
else dp1[j]=a[j];
}dp2[n-1]=a[n-1];
for(int j=n-2;j>=0;j--)
else dp2[j]=a[j];
}max1[0]=dp1[0];
for(int j=1;jdp1[j]?max1[j-1]:dp1[j]);
}max2[n-1]=dp2[n-1];
for(int j=n-2;j>=0;j--)
int max=-400000;
for(int j=1;jprintf("%d\n",max);
}return 0;
}
POJ 2479 最大子段和
poj 2479 最大子段和 poj 2479嚴格來說不是單純的最大子段和,它是乙個雙向的最大子段和,為了弄清雙向的最大子段和就必須弄清楚單向的最大子序和。單向最大子段和問題如下 在序列a 1.n 任意乙個ai都是整數,有正有負 中找出乙個子串行a p.q 使得m ap ap 1 aq 1 aq最大...
poj2479分步DP精簡成O n 演算法
提取資訊包括從s到t之間的和 但是n較大這樣dp i j 的形式顯然不行,那麼如果轉換 其實我們除了記錄 i,j 之間的和那麼可以記錄以i開頭和以i結尾兩種情況 後來發現根本不用記錄以什麼為開頭或者結尾,每次更新前面一段值就行 725k 438ms include using namespace s...
簡單的正念冥想法
近二十年來的研究證明,冥想可以改變思維 改善專注力,它能重塑我們的大腦。冥想還可以降低焦慮程度,有利於情緒 身體的健康,增強身心免疫力。好東西一定要分享。平和是可以傳染的,快樂是可以傳染的,幸福也是可以傳染的。簡單的正念冥想法 mindful meditation 1,選擇自己覺得最舒適的坐姿 2,...