[BZOJ 1597] Usaco2008 Mar 土地购买 · 斜率优化DP

来源:互联网 发布:ajax接收不到json数据 编辑:程序博客网 时间:2024/05/29 03:56

拿到手的时候根本想不到是斜率优化。。。然而思路太神了。

对于两块地x1*y1 x2*y2,如果x1<=x2 && y1<=y2,那么前一块地就可以忽略掉,所以我们先按x1升序排序,然后做一遍类似单调队列的操作把所有可以忽略的地块去掉。

这样我们可以得出平方级别的DP方程:

现在开始斜率优化:

假设j>k且j优于k,那么满足

化简得到

然后就随便写写呗~

虽然各种奇葩错误WA了无数次

#include <stdio.h>#include <algorithm>#include <string.h>#include <cstdlib>using namespace std;#define ll long longconst int N=50005;struct arr{ll x,y;}b[N],a[N];ll n,m,q[N],l,r;ll f[N];bool cmp(const arr A,const arr B){if (A.x==B.x) return A.y>B.y;return A.x<B.x;}ll getX(ll x,ll y){return a[y+1].y-a[x+1].y;}ll getY(ll x,ll y){return f[x]-f[y];}int main(){scanf("%lld",&n);for (ll i=1;i<=n;i++)scanf("%lld%lld",&b[i].x,&b[i].y);sort(b+1,b+n+1,cmp);for (ll i=1;i<=n;i++){while (m && b[i].y>=a[m].y) m--;a[++m]=b[i];}q[0]=l=r=0;for (ll i=1;i<=m;i++){while (l<r && getY(q[l+1],q[l])<=a[i].x*getX(q[l+1],q[l])) l++;ll j=q[l];f[i]=f[j]+a[j+1].y*a[i].x;while (l<r && getY(q[r],q[r-1])*getX(i,q[r])>=getY(i,q[r])*getX(q[r],q[r-1])) r--;q[++r]=i;for (int i=1;i<=n;i++)}printf("%lld\n",f[m]);return 0;}


0 0
原创粉丝点击