[bzoj1597][Usaco2008 Mar]土地购买

f[i]=min(f[j]+b[j+1]*a[i])

f[j]+b[j+1]*a[i]<f[k]+b[k+1]*a[i]

$a[i] > \frac{f[j]-f[k]}{b[k+1]-b[j+1]}$

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MN 50000
#define ll long long
#define int long long
using namespace std;
{
int x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}

int n,m;
struct sq{int a,b;}s[MN+5],l[MN+5];
ll f[MN+5];
bool cmp(sq x,sq y){return x.a<y.a||(x.a==y.a&&x.b<y.b);}
int q[MN+5],top,tail;

double calc(int x,int y)
{
return (double)(f[x]-f[y])/(s[x+1].b-s[y+1].b);
}

int get(int x)
{
while(top>tail&&-x<calc(q[tail+1],q[tail])) tail++;
return q[tail];
}

void ins(int x)
{
while(top>tail&&calc(x,q[top])>calc(q[top],q[top-1]))--top;
q[++top]=x;
}

main()
{
sort(l+1,l+n+1,cmp);
for(int i=1;i<=n;i++)
{
while(m&&l[i].b>=s[m].b) --m;
s[++m]=l[i];
}
q[top=tail=1]=0;//f[1]=1LL*s[1].a*s[1].b;
for(int i=1;i<=m;i++)
{
int from=get(s[i].a);
f[i]=f[from]+1LL*s[from+1].b*s[i].a;
ins(i);
}
cout<<f[m];
return 0;
}

FallDream代表秋之国向您问好！ 欢迎您来我的博客www.cnblogs.com/FallDream
posted @ 2017-03-29 09:20  FallDream  阅读(184)  评论(0编辑  收藏  举报