BZOJ 1597: [Usaco2008 Mar]土地购买 动态规划 + 斜率优化
Code:
#include<bits/stdc++.h> #define maxn 1000000 #define ll long long #define x(i) (b[i+1]) #define y(i) (f[i]) #define setIO(s) freopen(s".in","r",stdin) using namespace std; int A[maxn],arr[maxn],q[maxn],tot,head,tail; ll a[maxn], b[maxn], f[maxn], u[maxn], v[maxn]; bool cmp(int i,int j) { return u[i]==u[j]?v[i]<v[j]:u[i]<u[j]; } double slope(int i,int j) { return (double)(1.00*y(i)-y(j))/(double)(1.00*x(j)-x(i)); } int main() { // setIO("input"); int n,i,j; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%lld%lld",&u[i],&v[i]),A[i]=i; sort(A+1,A+1+n,cmp); for(i=1;i<=n;++i) { while(v[A[i]]>=b[tot]&&tot) --tot; ++tot, a[tot]=u[A[i]], b[tot]=v[A[i]]; } n=tot,head=tail=0; for(i=1;i<=n;++i) { while(head<tail&&slope(q[head],q[head+1])<a[i]) ++head; f[i]=f[q[head]]+a[i]*b[q[head]+1]; while(head<tail&&slope(q[tail], i)<slope(q[tail-1],i)) --tail; q[++tail]=i; } printf("%lld\n",f[n]); return 0; }