『土地征用 Land Acquisition 斜率优化DP』

斜率优化DP的综合运用,对斜率优化的新理解。
详细介绍见『玩具装箱TOY 斜率优化DP』


土地征用 Land Acquisition(USACO08MAR)

Description

Farmer John is considering buying more land for the farm and has his eye on N (1 <= N <= 50,000) additional rectangular plots, each with integer dimensions (1 <= width_i <= 1,000,000; 1 <= length_i <= 1,000,000).

If FJ wants to buy a single piece of land, the cost is $1/square unit, but savings are available for large purchases. He can buy any number of plots of land for a price in dollars that is the width of the widest plot times the length of the longest plot. Of course, land plots cannot be rotated, i.e., if Farmer John buys a 3x5 plot and a 5x3 plot in a group, he will pay 5x5=25.

FJ wants to grow his farm as much as possible and desires all the plots of land. Being both clever and frugal, it dawns on him that he can purchase the land in successive groups, cleverly minimizing the total cost by grouping various plots that have advantageous width or length values.

Given the number of plots for sale and the dimensions of each, determine the minimum amount for which Farmer John can purchase all

约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地。如果约翰单买一块土 地,价格就是土地的面积。但他可以选择并购一组土地,并购的价格为这些土地中最大的长 乘以最大的宽。比如约翰并购一块3 × 5和一块5 × 3的土地,他只需要支付5 × 5 = 25元, 比单买合算。 约翰希望买下所有的土地。他发现,将这些土地分成不同的小组来并购可以节省经费。 给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。

Input Format

  • Line 1: A single integer: N
  • Lines 2..N+1: Line i+1 describes plot i with two space-separated integers: width_i and length_i

Output Format

  • Line 1: The minimum amount necessary to buy all the plots.

Sample Input

4
100 1
15 15
20 5
1 100

Sample Output

500

解析

这是一道\(USACO\)的题,相比之前的玩具装箱,难度较大,我们通过这道题来更透彻地理解斜率优化\(DP\)。
显然,这不是一道明显的\(DP\)题,我们需要先做一些转换。有一个很明显的贪心,如果一块土地\(P\)的长和宽都大于另一块土地\(Q\)的话,那么显然\(Q\)我们是可以无视的,应为我们在购买\(P\)时,可以顺便购买\(Q\),不会带来任何额外的花费。

STEP 1: 解决预备问题

  • 为了建立合适的\(DP\)模型,我们先要处理题面中的一些其他的问题。

这里我们使用栈来解决无用土地这个问题。
先将所有土地存入一个结构体中,然后就可以以长度\(l\)为第一关键字,宽度\(w\)为第二关键字对土地进行排序。排序完成后,我们需要将土地一一加入栈。
在加入一块土地时,我们需要检查:栈顶的土地的宽度是否小于等于这块土地的宽度,由排序可知,栈顶的土地的长度一定小于等于这块土地的长度,如果栈顶的土地的宽度也小于等于这块土地的宽度的话,我们就可以判定当前栈顶的土地是一块无用土地。那么,可以将栈顶土地直接弹出。
最后,栈中剩下的土地就是有效的土地。我们将其重新取出,并重新以长度\(l\)为第一关键字,宽度\(w\)为第二关键字对土地进行排序。

STEP 2: 建立DP模型

  • 在处理完其他问题后,我们需要建立朴素\(DP\)模型。

这时候,如果我们将所得的有效土地视为一个个矩形,排序后,放在平面直角坐标系中应满足:长度\(x\)随着下标的增大而增大,高度\(y\)随着下标的增大而减小,如下图所示。

设\(f_i\)代表购买了前i块土地的最小花费,利用排序后的性质,那么我们就可以建立状态转移方程:
\[
f_i=\min_{j<i}\{y_{j+1}x_i+f_j\}
\]

STEP 3: 建立斜率函数

  • 得到了\(DP\)方程后,观察得知,方程形如\(f_i=min/max\{a_i+b_j+kc_id_j+f_j\}\),即:方程中除了含有\(f_j\)以及单独和\(i,j\)有关的项外,还含有既和i有关,又和j有关的项。对于这种方程,我们考虑斜率优化。首先,我们需要利用状态转移方程建立斜率函数。

加入我们找到了最优的\(f_j\),那么由方程可得:
\[
f_i=y_{j+1}x_i+f_j
\\?f_j=-y_{j+1}x_i+f_i
\]
通常,我们视\(f_j\)为\(y\),既和\(i\)有关,又和\(j\)有关的项中,视和\(i\)有关的部分为\(k\),和\(j\)有关的部分为\(x\),方程中的其余项为\(b\)。那么就可以得到斜率函数\(y=kx+b\)。
这里,出现了一种特殊情况:既和\(i\)有关,又和\(j\)有关的项是负数,那么我们通常将负号看做是与\(y\)有关的项的。
那么结果就是:视\(f_j\)为\(y\),视\(-y_{j+1}\)为\(x\),视\(x_i\)为\(k\),视\(f_i\)为\(b\),得到\(y=kx+b\)。

STEP 4: 分析单调性及凸包的性质

  • 得到斜率函数后,我们需要通过图像分析其性质,完成代码实现。

首先,我们得出函数的性质:

1.过定点\(P_j(-y_{j+1},f_j)\)
2.斜率为\(x_i\)

再通过我们之前得出的性质:土地高度\(y\)随着下标的增大而减小,以及花费\(f_j\)满足随着\(j\)的增大而增大,可以画出如下图像。

满足斜率为\(x_i\)的直线自上向下移动,由于我们需要截距\(f_i\)最小,当他碰到第一个\(P_j\)时,我们便得到了最优决策\(j\)。

注意到\(x_i\)满足单调上升,\(P\)点围成的凸包的两两节点之间的斜率也满足单调递增,就可以得到如下性质。

1.\(slope(P_j,P_{j+1})>x_i\)且\(slope(P_{j-1},P_j)<x_i\)时,\(j\)为最优决策,否则\(j\)永远不会成为最优决策
2.\(slope(P_x,P_y)>slope(P_x,P_{y'})\),决策\(y'\)优于\(y\)

确认其具有如上性质后,单调队列维护即可。

STEP 5: 代码实现

  • 确立作法后,我们需要代码实现

注意事项

1.斜率函数中的斜率满足单调递增(递减)时,可以使用单调队列维护,转移均摊时间复杂度\(O(1)\)
2.斜率函数中的斜率不满足单调递增(递减),但满足两两节点之间的斜率单调递增的凸包存在时(即性质\(2\)有效时),可以使用单调栈维护,二分查找找到最优决策,转移均摊时间复杂度\(O(log_2n)\)
3.\(slope\)函数的返回值为\(double\)类型
4.注意是否需要开长整型变量\((longlong)\)

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
const int N=50000+80;
struct earth{long long x,y;}a[N],Stack[N],d[N];
long long n,top=0,f[N],q[N*2],head=1,tail=1;
inline bool cmp(earth p1,earth p2){if(p1.x==p2.x)return p1.y<p2.y;else return p1.x<p2.x;}
inline void input(void)
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&a[i].x,&a[i].y);
}
inline void init(void)
{
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        while(top&&Stack[top].y<=a[i].y)top--;
        Stack[++top]=a[i];
    }
    for(int i=1;i<=top;i++)
    {
        d[i]=Stack[i];
    }
    sort(d+1,d+top+1,cmp);
}
inline double slope(long long p,long long q){return (f[q]-f[p])*1.0/(d[p+1].y-d[q+1].y);}
inline void dp(void)
{
    f[0]=0;
    for(int i=1;i<=top;i++)
    {
        while(head<tail&&slope(q[head],q[head+1])<d[i].x)head++;
        f[i]=f[q[head]]+d[q[head]+1].y*d[i].x;
        while(head<tail&&slope(q[tail-1],q[tail])>slope(q[tail-1],i))tail--;
        q[++tail]=i;
    }
}
int main(void)
{
    input();
    init();
    dp();
    printf("%lld\n",f[top]);
}


『土地征用 Land Acquisition 斜率优化DP』

原文地址:https://www.cnblogs.com/Parsnip/p/10335810.html

时间: 2024-10-13 14:31:54

『土地征用 Land Acquisition 斜率优化DP』的相关文章

斜率优化DP总结

前言: 也是好久没有写题解了,最近主要学习了单调栈单调队列以及斜率优化DP这几个知识点,对于较难的斜率优化DP,做个小小的总结吧. 正(che)文(dan): T1 hdu 3507 在一个风和日丽的早上,你打开了网页,点进了hdu,偶然间看到了这道题,不屑的以为这仅仅是一个很水的DP,2分钟给出DP方程式,很快的写完后发现n的范围居然是500000,这让已经推出来的 O(n2)复杂度的递推式情何以堪,所以就产生了一种高逼格的优化方式:斜率优化. 这道题的方程式是什么呢? dp[i]=min(d

bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免精度误差,输出结果时输出v×m^2. In

[bzoj 1911][Apio 2010]特别行动队(斜率优化DP)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911 分析: 首先可以的到裸的方程f[i]=max{f[j]+a*(Si-Sj)^2+b*(Si-Sj)+c} 0<j<i 简化一下方程,我们知道对于一次项,最后结果肯定是b*Sn 所以可以写成f[i]=max{f[j]+a*(Si-Sj)^2+c} 0<j<i 我们不妨设0<x<y<i,且x比y优 即f[x]+a*(Si-Sx)^2+c>f[y]+a*

hdu 2993 MAX Average Problem (斜率优化dp入门)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5855    Accepted Submission(s): 1456 Problem Description Consider a simple sequence which only contains positive integers as

hdu3507之斜率优化DP入门

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 4780    Accepted Submission(s): 1437 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu

bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对

HDU3045 Picnic Cows(斜率优化DP)

Picnic Cows Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2192    Accepted Submission(s): 675 Problem Description It’s summer vocation now. After tedious milking, cows are tired and wish to t

BZOJ 1096 [ZJOI2007]仓库建设 斜率优化dp

1096: [ZJOI2007]仓库建设 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1096 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚. 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场

HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)

题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程很容易想出来,dp[i][j] 表示前 j 个数分成 i 组.但是复杂度是三次方的,肯定会超时,就要对其进行优化. 有两种方式,一种是斜率对其进行优化,是一个很简单的斜率优化 dp[i][j] = min{dp[i-1][k] - w[k] + sum[k]*sum[k] - sum[k]*sum[