nkoj 3686 最大子段和
時間限制 : - ms 空間限制 : 65536 kb
問題描述
給你乙個包含n個整數的序列,要求從中取出m個不相交的子段,要求這m個子段的和盡肯能大,輸出這個最大和。
例如,n=7,m=2, 序列如下:
-2 1 4 -2 3 -2 3
最優方案取出的兩段為 這兩段的和為9
輸入格式
第一行,兩個整數n和m
第二行,n個空格間隔的整數,表示整數數列
輸出格式
一行,乙個整數,表示所求答案
樣例輸入
7 2
-2 1 4 -2 3 -2 3
樣例輸出
9提示
1<=n <=100,000 1<=m<=300 且 m<=n
數列中的數字範圍[-50000,50000]
思路:
1、階段:從左往右討論每乙個數字。
2、狀態:f[i][j]表示從前j個數中選出i段的最大和,且j必須作為最後一段結尾
3、決策:討論第j個數加不加入第i段中
4、方程:
f[i][j]=a[1]+a[2]+a[3]+a[4]…+a[j] (i==j)
f[i][j]=max (i< j<=n)
//不選a[j]的情況:當討論到a[i]後面的數時,選出的最佳方案可能不包含a[i];
邊界條件:1<=i<=m, i<=j<=n, i-1<=k<=j-1
優化:
1、空間:考慮到本題空間限制64m,所以需使用滾動陣列
改寫方程如下:
f[i&1][j]=max (i< j<=n)
f[i&1][j]=a[1]+a[2]+a[3]+a[4]…+a[j] (i==j)
注意當討論到f[i][j]時,所得的f[i][j]值需要更新best[j]值,但未更新的best[j]值需要在下一迴圈使用,所以使用temp將需要更新的best[j]值存下,等下一迴圈使用完畢後再更新。且當i==m迴圈中最終的temp值即為所求答案。
**:
#include
#include
using
namespace
std;
#define ll long long
const ll inf=1000000000000000000ll;
ll a[100003];
ll f[2][100003],best[100003],qian[100003];
int main()
ll temp;
for(int i=1;i<=m;i++)
} printf("%i64d",temp);
}
第二種解決方案是只用乙個變數temp儲存,但注意i=1時需提前計算,以及最終答案需要單獨尋找
詳見**:
#include
#include
using
namespace
std;
#define ll long long
const ll inf=1000000000000000000ll;
ll a[100003];
ll f[2][100003],qian[100003];
int main()
ll temp;
for(int i=1;i<=n;i++)
for(int i=2;i<=m;i++)
} }
ll ans=-inf;
for(int i=m;i<=n;i++) if(f[m&1][i]>ans) ans=f[m&1][i];//注意i範圍
printf("%i64d",ans);
}
Employment Planning 動規小練
employment planning 原題鏈結 對於當前月份所需人數,和僱傭最大所需人數之間的情況進行討論。由於解雇金額和僱傭金額的存在,會存在一次性僱傭更多的人以減少解雇金額的情況,所以要討論到所需最大人數。include include include include include incl...
2016 7 13 樹形動規
rmq演算法講完沒幾個小時,我們就開始了小紫中的一節 足見這個演算法很重要 樹形動歸 1.焦作一中資訊學oy 2.小黃 資訊學奧賽一本通 3.小紫 演算法競賽入門經典第二版 題型總結 來自資料1 1 加分二叉樹 區間動規 樹的遍歷 2 二叉蘋果樹 二叉樹上的動規 3 最大利潤 多叉樹上的動規 4 選...
序列型動規
d i 中的i表示前i的元素的某種性質。有一排n棟房子,每棟房子要漆成k種顏色中的一種 任何兩棟相鄰的房子不能漆成同樣的顏色 房子i染成第j種顏色的花費是cost i j 問最少需要花多少錢油漆這些房子 輸入 n 3,k 3 cost 14,2,11 11,14,5 14,3,10 輸出 10 房子...