洛谷2900 [USACO08MAR]土地征用Land Acquisition （斜率优化+dp）

$dp[i]=dp[j-1]+h[j]*mn[j][i]$

qwq我们发现对于一个含有最值的柿子，他没法转移qwq

$$dp[i]=max(dp[j-1]+h[j]*w[i])$$

$\frac{dp[j-1]-dp[k-1]}{h[j]-h[k]} > -w[i]$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
#define int long long
using namespace std;
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 2e5+1e2;
struct Node{
int h,w;
};
Node a[maxn];
int dp[maxn];
int n;
struct Point{
int x,y;
};
Point q[maxn];
int chacheng(Point x,Point y)
{
return x.x*y.y-x.y*y.x;
}
bool count(Point i,Point j,Point k)
{
Point x,y;
x.x=k.x-i.x;
x.y=k.y-i.y;
y.x=k.x-j.x;
y.y=k.y-j.y;
if (chacheng(x,y)>=0) return true;
return false;
}
void push(Point x)
{
while(tail>=head+1 && count(q[tail-1],q[tail],x)) tail--;
q[++tail]=x;
}
void pop(int lim)
{
}
bool cmp(Node a,Node b)
{
if(a.h==b.h) return a.w>b.w;
return a.h>b.h;
}
signed main()
{
sort(a+1,a+1+n,cmp);
push((Point){a[1].h,0});
dp[1]=a[1].w*a[1].h;
int mx = a[1].w;
for (int i=2;i<=n;i++)
{
if (a[i].w<=mx)
{
dp[i]=dp[i-1];
continue;
}
mx=max(mx,a[i].w);
dp[i]=dp[i-1]+a[i].w*a[i].h;
pop((-1ll)*a[i].w);
Point now = q[head];
dp[i]=min(now.y+a[i].w*now.x,dp[i]);
push((Point){a[i].h,dp[i-1]});
}
cout<<dp[n];
return 0;
}


posted @ 2018-12-27 16:49  y_immortal  阅读(98)  评论(0编辑  收藏  举报