有n個人,每個人都有乙個戰力值,將這n個人分成若干個段(每個段內的人的編號都是連續的),每個段的初始戰力值為每個段內的人的戰力值的總和
給出常數a,b,c,而每個段的真正戰力值為ax2+bx+c(x為這個段的初始戰力值),求出分成若干個段得到的所有段的最大真正戰力值總和
dp很容易想到
設f[i]為將前i個人分成若干段的最大真正戰力值,s[i]為前i個人戰力值總和
可以得到:f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b+c)
但這道題資料極大
所以用斜率優化dp
設j1f[j2]+(s[i]-s[j2])*(s[i]-s[j2])*a+(s[i]-s[j2])*b+c>f[j1]+(s[i]-s[j1])*(s[i]-s[j1])*a+(s[i]-s[j1])*b+c
化簡得到:(f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s[j2]-s[j1])*b)/(s[j2]-s[j1])>2*a*s[i]
然後做斜率優化就可以了
注意要加long long
來自蒟蒻的吐槽:這道題!!我其實應該在n久之前就應該a了,結果在斜率優化的時候把slop(list[head],list[head+1])錯手打成了slop(list[head],list[head]+1),痛心疾首
#include#include#include
#include
#include
using
namespace
std;
typedef
long
long
ll;ll a,b,c;
ll s[
1100000
];ll f[
1100000
];/*
f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b+c)
f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b)+c
j1f[j1]+(s[i]-s[j1])*(s[i]-s[j1])*a+(s[i]-s[j1])*b
f[j2]+s[i]*s[i]*a-2*a*s[i]*s[j2]+s[j2]*s[j2]*a+s[i]*b-s[j2]*b > f[j1]+s[i]*s[i]*a-2*a*s[i]*s[j1]+s[j1]*s[j1]*a+s[i]*b-s[j1]*b
f[j2]-2*a*s[i]*s[j2]+s[j2]*s[j2]*a-s[j2]*b > f[j1]-2*a*s[i]*s[j1]+s[j1]*s[j1]*a-s[j1]*b
(f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s[j2]-s[j1])*b)/(s[j2]-s[j1]) >2*a*s[i]
*/ll slop(
int j1,int
j2)int list[1100000
];int
main()
int head=1,tail=1;list[1]=0
;
for(int i=1;i<=n;i++)
printf(
"%lld\n
",f[n]);
return0;
}
BZOJ 1911 APIO2010 特別行動隊
題目描述 因為是從別人部落格裡斜率優化分類一欄找的題目,所以 這題被我秒了。顯然先預處理字首和s i ik 1 xi 設 d i 為將前i 個士兵分組的最大修正後戰鬥力。d i max maxm ax a s i 2 b s i c設 kixj biyj 2a s i s j d i a s i 2...
bzoj1911 Apio2010 特別行動隊
題目鏈結 給出乙個序列,將序列分成連續的幾段,每段的價值為a s s b s c,其中a,b,c為給定常數,s為這一段中所有數之和。求最大價值和。斜率優化。dp方程 其中 為字首和,表示從1 i的最大價值。斜率式 所以決策 對映到平面直角座標系上就是 斜率 為正且單增 橫座標 單減 小於0,單增 所...
bzoj 1911斜率優化
這個題為什麼有個 關於斜率優化又有了新的感悟 對於次優解的排除 假設對於i來說l是次優解。即滿足k q l q l 1 k i 時,l 1比l更優 k q l q l 1 表示這兩個點連成一條線的斜率,k i 表示在i處那根線的斜率,這個很容易就可以證明 對於提前排除不可能的解 假設r是考慮排除的點...