• [bzoj] 1597 土地购买 || 斜率优化dp


    原题

    农夫John准备扩大他的农场,他正在考虑N块长方形的土地. 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. FJ希望买下所有的土地,但是他发现分组来买这些土地可以节省经费. 他需要你帮助他找到最小的经费.


    首先,我们发现有一些矩形是没有用的!(假如他的x和y都比另一个矩形小)然后我们把它删掉!
    我们就得到了x升序,y降序的矩阵序列

    显然是dp
    n^2的dp:
    dp[i]表示买完前i块土地的最小花费

    //按x坐标sort
    for (int i=1;i<=n;i++)
        for (int j=1;j<i;j++)
            dp[i]=min(dp[i],dp[j]+x[i]*y[j+1]);
    

    怎么优化呢?
    假如i可以由j和k转移过来,而j状态比k状态优,那么
    (dp[j]+x[i]*y[j+1]<dp[k]+x[i]*y[k+1])
    移项为(dp[j]-dp[k]<x[i]*(y[k+1]-y[j+1]))
    再除过去得到((dp[j]-dp[k])/(y[k+1]-y[j+1])<x[i])
    然后维护单调队列即可!(如果j比k优,那么k能更新的j都能更新)

    #include<cstdio>
    #include<algorithm>
    #define N 50010
    typedef long long ll;
    using namespace std;
    struct hhh
    {
    	ll x,y;
    	bool operator < (const hhh &b) const
    	{
    		if (x==b.x) return y<b.y;
    		return x<b.x;
    	}
    }a[N];
    ll n,tot,x[N],y[N],q[N],f[N],l,r;
    
    ll read()
    {
    	ll ans=0,fu=1;
    	char j=getchar();
    	for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
    	for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
    	return ans*fu;
    }	
    
    double check(ll i,ll j)
    {
    	return 1.0*(f[j]-f[i])/(y[i+1]-y[j+1]);
    }
    
    int main()
    {
    	freopen("buy.in","r",stdin);
    	freopen("buy.out","w",stdout);
    	n=read();
    	for (ll i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    	sort(a+1,a+n+1);
    	for (ll i=1;i<=n;i++)
    	{
    		while (tot && a[i].y>=y[tot]) tot--;
    		x[++tot]=a[i].x;
    		y[tot]=a[i].y;
    	}
    	for (ll i=1;i<=tot;i++)
    	{
    		while (l<r && check(q[l],q[l+1])<x[i]) l++;
    		f[i]=f[q[l]]+y[q[l]+1]*x[i];
    		while (r>l && check(q[r],i)<check(q[r-1],q[r])) r--;
    		q[++r]=i;
    	}
    	printf("%lld
    ",f[tot]);
    	return 0;
    }
    
  • 相关阅读:
    Linux架构
    Python标准库09 当前进程信息 (os包)
    Linux从程序到进程
    Python标准库04 文件管理 (部分os包,shutil包)
    Python标准库10 多进程初步 (multiprocessing包)
    Python标准库06 子进程 (subprocess包)
    绘图: matplotlib Basemap简介
    树莓派与Linux
    绘图: Python matplotlib简介
    Linux进程间通信
  • 原文地址:https://www.cnblogs.com/mrha/p/8392812.html
Copyright © 2020-2023  润新知