東東每個學期都會去寢室接受掃樓的任務,並清點每個寢室的人數。
每個寢室裡面有ai個人(1<=i<=n)。從第i到第j個宿舍一共有sum(i,j)=a[i]+…+a[j]個人
這讓宿管阿姨非常開心,並且讓東東掃樓m次,每一次數第i到第j個宿舍sum(i,j)
問題是要找到sum(i1, j1) + … + sum(im,jm)的最大值。且ix <= iy <=jx和ix <= jy <=jx的情況是不被允許的。也就是說m段都不能相交。
注:1 ≤ i ≤ n ≤ 1e6 , -32768 ≤ ai ≤ 32767 人數可以為負數。。。。(1<=n<=1000000)
令f[i][j]是前i個掃j次的最大值(一定會掃a[i]),f[i][j]=max j-1<=k<=i-1(分為i與前面一起掃和i單獨掃兩種情況)。
發現可以優化掉陣列第二維j。
即遍歷j=1~m,f[i]=max。
然後f[k]可以取掃j-1次的f[j-1]~f[i-1]最大值: 令maxf[i]為j-1次的f[j-1]~f[i]最大值,f[i]=max。
注意maxf[i]的更新,這一輪j的maxf要在下一輪j+1使用。
最後答案是f[m]~f[n]中的最大值, 不能從f[1]~f[n]中取最大值,因為前k個是只掃了k輪(k一道動態規劃題目,想公式很費勁,優化也不好想。多做一些dp題應該會有改善。
#include
#include
using
namespace std;
//令f[i][j]是前i個掃j次的最大值(一定會掃a[i])
//f[i][j]=max j-1<=k<=i-1
//發現可以優化掉j
//即遍歷j=1~m
//f[i]=max
//然後f[k]可以取掃j-1次的f[j-1]~f[i-1]最大值
//令maxf[i]為j-1次的f[j-1]~f[i]最大值
//f[i]=max
int m,n;
int a[
1000010];
int f[
1000010];
int maxf[
1000010];
int ans;
intmain()
}for
(int i=m;i<=n;i++
)//注意從m開始,不然前k個為只掃k輪(kif
(ans) ans=f[i]
;printf
("%d\n"
,ans);}
}
WEEK12 作業 C 必做題3
東東每個學期都會去寢室接受掃樓的任務,並清點每個寢室的人數。每個寢室裡面有ai個人 1 i n 從第i到第j個宿舍一共有sum i,j a i a j 個人 這讓宿管阿姨非常開心,並且讓東東掃樓m次,每一次數第i到第j個宿舍sum i,j 問題是要找到sum i1,j1 sum im,jm 的最大值...
Week12作業 必做題
a給出n個數,zjm想找出出現至少 n 1 2次的數,現在需要你幫忙找出這個數是多少?input 本題包含多組資料 每組資料報含兩行。第一行乙個數字n 1 n 999999 保證n為奇數。第二行為n個用空格隔開的整數。資料以eof結束。output 對於每一組資料,你需要輸出你找到的唯一的數。實現 ...
Week12 必做題3(動態規劃)
東東每個學期都會去寢室接受掃樓的任務,並清點每個寢室的人數。每個寢室裡面有ai個人 1 i n 從第i到第j個宿舍一共有sum i,j a i a j 個人 這讓宿管阿姨非常開心,並且讓東東掃樓m次,每一次數第i到第j個宿舍sum i,j 問題是要找到sum i1,j1 sum im,jm 的最大值...