bzoj1597: [Usaco2008 Mar]土地购买
这道题...写的第一道斜率优化dp 其实就是把题目转换完维护一个凸包
具体解释推荐一个博客 http://www.cnblogs.com/akhpl/p/6715148.html
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=50007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL x[M],y[M],f[M]; int q[M],n,tot; struct node{LL x,y;}a[M]; bool cmp(node a,node b){return a.x!=b.x?a.x<b.x:a.y<b.y;} double slop(int a,int b){return (double)(f[b]-f[a])/(y[a+1]-y[b+1]);} int main() { n=read(); for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++){ while(tot&&y[tot]<=a[i].y) tot--; x[++tot]=a[i].x; y[tot]=a[i].y; } int head=0,tail=0; for(int i=1;i<=tot;i++){ while(head<tail&&slop(q[head],q[head+1])<x[i]) head++; int v=q[head]; f[i]=f[v]+y[v+1]*x[i]; while(head<tail&&slop(q[tail-1],q[tail])>slop(q[tail],i)) tail--; q[++tail]=i; } printf("%lld\n",f[tot]); return 0; }