[Usaco2008 Mar]土地购买

题外话:丫的手贱不小心删了,只好重打。。。

如果CSDN能回复回收站的东东那该有多好啊

此题依旧是斜率优化。
感觉自己做斜率优化做疯了(滑稽)
还是与先前一样弄出DP式:

f[i]=min{f[j]+y[j+1]*x[i]}

这里要着重说明一下:
这里的x[],y[]都已经是排过序并整理了的!!!
我们先按照x为第一关键字,y为第二关键字来从小到大(both)排序。
随后,我们发现它的y[]不满足单调性。
所以我们应当将其转换一下。

这位大佬写得很详细:%d%a%l%a%o

这样子,我们就可以斜率优化了。
设k<j<i,且j别k更优。
f[j]+y[j+1]*x[i]<f[k]+y[k+1]*x[i]

(f[j]-f[k])/(y[k+1]-y[j+1])<a[i]

上标:

#include<cstdio>
#include<algorithm>
#define N 50010
#define db double
#define ll long long
using namespace std;
struct node{ll x,y;}a[N];
int n,g[N],len=0,l=0,tot=1;
ll f[N];

inline int read()
{
	int x=0; char c=getchar();
	while (c<'0' || c>'9') c=getchar();
	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x;
}

int cmp(node x,node y) {return x.x==y.x ? x.y<y.y:x.x<y.x;}

db solve(int x,int y) {return (db)(f[x]-f[y])/(a[y+1].y-a[x+1].y);}

int main()
{
//	freopen("1597.in","r",stdin);
//	freopen("1597.out","w",stdout);
	n=read();
	for (int i=1;i<=n;i++)
		a[i].x=read(),a[i].y=read();
	sort(a+1,a+n+1,cmp);
	for (int i=2;i<=n;i++)
	{
		while (a[i].y>=a[tot].y && tot) tot--;
		a[++tot]=a[i];
	}
	for (int i=1;i<=tot;i++)
	{
		while (l<len && solve(g[l+1],g[l])<a[i].x) l++;
		f[i]=f[g[l]]+a[g[l]+1].y*a[i].x;
		while (l<len && solve(g[len],g[len-1])>solve(i,g[len])) len--;
		g[++len]=i;
	}
	printf("%lld
",f[tot]);
	return 0;
}

转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817593.html