bzoj1597 [Usaco2008 Mar]土地購買
阿新 • • 發佈:2018-03-28
bzoj1597 需要 usaco desc 每一個 post inline cmp 專題
我們就去湊那個式子
先按x從小到大排序。。。因為已經去掉了不用的土地,那麽此時的y一定就是從大到小排的序
\(dp[i]\)表示買前\(i\)塊土地的最優解,所以有了狀態轉移方程方程:
\(dp[i] = dp[j] + x[i] * y[j+1]\)
寫成一次函數的形式:
\(-dp[j]=y[j+1]*x[i]-dp[i]\)
所以每一個點就是\((y[j+1],-dp[j])\)
\(k=x[i]\)滿足單調性
當然這裏就差不多了,但是由於上一篇我說的不是很清楚,我想再多說一句。。。
最開始排除的是兩個點的斜率小於\(k\)的,其實是因為畫圖可以看出後面的點答案一定優於前面的。而當斜率大於k時,雖然當前的答案時前面的點更好(所以計算答案的時候就用的是第一個滿足條件的點),但是由於\(k\) 在單增,有可能\(k\)會超過它的斜率,所以蹦年確定。
而倒著刪是因為如果不是個下凸包形狀的話,那麽中間那個點一定不是最優點,要麽它前面的那個點是最優的,要麽後面的是最優的。
[Usaco2008 Mar]土地購買
Time Limit: 10 Sec Memory Limit: 162 MB
Description
農夫John準備擴大他的農場,他正在考慮\(N (1 <= N <= 50,000)\)塊長方形的土地. 每塊土地的長寬滿足\((1 <= 寬 < = 1,000,000; 1 <= 長 <= 1,000,000)\). 每塊土地的價格是它的面積,但FJ可以同時購買多快土地. 這些土地的價
格是它們最大的長乘以它們最大的寬, 但是土地的長寬不能交換. 如果FJ買一塊\(3*5\)的地和一塊\(5*3\)的地,則他需要
付\(5*5=25\). FJ希望買下所有的土地,但是他發現分組來買這些土地可以節省經費. 他需要你幫助他找到最小的經費.
Input
- 第1行: 一個數:$ N$
第\(2..N+1\)行: 第\(i+1\)行包含兩個數,分別為第\(i\)塊土地的長和寬
Output
第一行: 最小的可行費用.
Sample Input
4
100 1
15 15
20 5
1 100Sample Output
500
輸入解釋:
共有4塊土地.
FJ分3組買這些土地:
第一組:100x1,
第二組1x100,
第三組20x5 和 15x15 plot.
每組的價格分別為100,100,300, 總共500.
顯然有些田是白送的2333.。。。。(只要存在有別的田比這塊田的長和寬都大,那麽這塊田直接白送。。。。。對吧)
然後把這些直接去掉。。。。
由於事先已經知道是斜率優化。。。(提示太明顯了。。感覺刷專題就這一點不怎麽好。。。)
先按x從小到大排序。。。因為已經去掉了不用的土地,那麽此時的y一定就是從大到小排的序
\(dp[i]\)表示買前\(i\)塊土地的最優解,所以有了狀態轉移方程方程:
\(dp[i] = dp[j] + x[i] * y[j+1]\)
寫成一次函數的形式:
\(-dp[j]=y[j+1]*x[i]-dp[i]\)
所以每一個點就是\((y[j+1],-dp[j])\)
\(k=x[i]\)滿足單調性
當然這裏就差不多了,但是由於上一篇我說的不是很清楚,我想再多說一句。。。
最開始排除的是兩個點的斜率小於\(k\)的,其實是因為畫圖可以看出後面的點答案一定優於前面的。而當斜率大於k時,雖然當前的答案時前面的點更好(所以計算答案的時候就用的是第一個滿足條件的點),但是由於\(k\)
而倒著刪是因為如果不是個下凸包形狀的話,那麽中間那個點一定不是最優點,要麽它前面的那個點是最優的,要麽後面的是最優的。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 5;
struct lpl{
long long x, y;
}lin, ini[maxn], field[maxn], point[maxn];
int n, tot, cnt, head, tail;
long long dp[maxn];
inline bool cmp(lpl a, lpl b)
{
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline void putit()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%lld%lld", &ini[i].x, &ini[i].y);
}
inline double slop(lpl a, lpl b)
{
return (double)(a.y - b.y) / (a.x - b.x);
}
inline void workk()
{
sort(ini + 1, ini + n + 1, cmp);
for(int i = 1; i <= n; i++){
while(tot && ini[i].y >= field[tot].y) tot--;
field[++tot] = ini[i];
}
point[head].x = field[1].y; point[head].y = 0;
for(int i = 1; i <= tot; ++i){
while(head < tail && slop(point[head], point[head + 1]) < field[i].x) head++;
dp[i] = (-point[head].y) + field[i].x * point[head].x;
lin.x = field[i + 1].y, lin.y = (-dp[i]);
while(head < tail && slop(point[tail], point[tail - 1]) > slop(point[tail], lin)) tail--;
point[++tail] = lin;
}
cout << dp[tot];
}
int main()
{
putit();
workk();
return 0;
}
bzoj1597 [Usaco2008 Mar]土地購買