题目大意:购买n个矩形,每块土地的价格是它的面积,但可以同时购买多块土地. 这些土地的价格是它们最大的长乘以它们最大的宽,求最少花费
题解:排序后用单调栈维护,去除无用数据(长宽都比令一块小的),然后就是naive斜率优化了 f[i]=min(f[j]+y[j+1]x[i]) f [ i ] = m i n ( f [ j ] + y [ j + 1 ] x [ i ] )
我的收获:去除冗杂数据
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 50005
int deq[M],n,tot;
long long dp[M];
struct cow{long long h,w;}a[M];
bool cmp(cow x,cow y){return x.h<y.h||(x.h==y.h&&x.w<y.w);}
inline long long up(int x,int y){return dp[y]-dp[x];}
inline long long down(int x,int y){return a[x+1].w-a[y+1].w;}
inline long long calc(int x,int y){return dp[x]+a[x+1].w*a[y].h;}
void work()
{
int l=1,r=0;deq[++r]=0;
for(int i=1;i<=n;i++){
while(l<r&&up(deq[l],deq[l+1])<=a[i].h*down(deq[l],deq[l+1])) l++;
dp[i]=calc(deq[l],i);
while(l<r&&up(deq[r-1],deq[r])*down(deq[r],i)>up(deq[r],i)*down(deq[r-1],deq[r])) r--;
deq[++r]=i;
}
printf("%lld\n",dp[n]);
}
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].h,&a[i].w);
sort(a+1,a+1+n,cmp);
int tot=0;
for(int i=1;i<=n;i++){
while(tot&&a[i].w>=a[tot].w) tot--;
a[++tot]=a[i];
}
n=tot;
}
int main()
{
init();
work();
return 0;
}