【筆記篇】斜率優化dp(五) USACO08MAR土地購(征)買(用)Land Acquisition
阿新 • • 發佈:2018-02-04
body 遞增 std char log lin 關鍵字排序 斜率優化 getchar
好好的題目連個名字都不統一..
看到這種最大最小的就先排個序嘛= =以x為第一關鍵字, y為第二關鍵字排序.
然後有一些\(x_i<=x_{i+1},且y_i<=y_{i+1}\)的土地就完全可以在買\(i+1\)的時候順便把\(i\)買了.
那麽現在就剩下了x遞增 y遞減的一串. 可以證明一次一起買的應該是連續的一段, 因為中間的y一定比左端點的大, x一定比右端點的小, 那麽一定可以在買左右端點的同時把中間的買走.
那就是常見套路了, 方程\(f[i]=f[j]+x[i]*y[\)\(j+1\)\(]\)
然後這個出奇地好化... 都不用數項數怕漏項了...\(f[j]\)=\(-x[i]\) \(*y[i+1]+\)\(f[i]\)...
但是吧, 我們按照這個式子找單調性的時候發現這個斜率總是與凸包的邊符號相反, 就會出問題..比如找不到該轉移的時候了... 反正我遇到這種情況一臉懵逼... 但是後來想想我tm可能是傻...其實就是= =
我們把方程寫成\(f[j]\)=\(x[i]\)\(*(-y[i+1])+\)\(f[i]\)這樣不就ok了麽= =
然後就變成了一道大水題(然而你不還是去除無用土地的時候去錯了麽(餵 你不要說出來啊 很丟人的QAQ))此人又日常精分了= =
代碼(這次壓過行了, 加了個struct和sort反而降到了18行)
#include <cstdio>
#include <algorithm>
const int N=5e4+5;typedef long long LL;
struct lot{int x,y;}l[N];LL f[N]; int q[N],h,t,n,m;
inline bool operator<(const lot&a,const lot&b){return (a.x==b.x)?a.y<b.y:a.x<b.x;}
double slope(int x,int y){return 1.0*(f[x]-f[y])/(l[y+1].y-l[x+1].y);}
inline int gn(int a=0,char c=0){for(;c<'0'||c>'9';c=getchar());
for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;}
int main(){m=gn();for(int i=1;i<=m;++i) l[i].x=gn(),l[i].y=gn();
std::sort(l+1, l+m+1);
for(int i=1;i<=m;++i){while(n>0&&l[n].y<=l[i].y) --n;l[++n]=l[i];}
for(int i=1;i<=n;++i){
while(h<t&&slope(q[h],q[h+1])<=l[i].x) ++h;
f[i]=f[q[h]]+1LL*l[i].x*l[q[h]+1].y;
while(h<t&&slope(q[t],q[t-1])>=slope(q[t],i)) --t;
q[++t]=i;
} printf("%lld",f[n]);
}
但是這篇好短啊OvO 算了短就短吧~
真實原因: 還有不到15min放學 作為蒟蒻應該A不掉另一道題再把這篇blog搞成二合一於是就這麽短放在這兒了. 其實更主要的原因是懶這種事情我怎麽會告訴你萌呢~
【筆記篇】斜率優化dp(五) USACO08MAR土地購(征)買(用)Land Acquisition