BZOJ 1597 [Usaco2008 Mar] 土地购买
题意:中文题意,自行理解;
思路:这个题和hdu 1300 的题很像,算是一种类似于二维的扩展,题目不是很难,但窝发现网上的一些题解有些地方说的不是很清楚,在计算斜率优化式的时候,tzw大牛的博客里适宜j为最优解来进行推导的斜率式,所以最后推出来的是维护小于,所以维护下凸包,而一般大家都习惯用k作为最优解,是所以推出来的式上凸包,谈后就是在前面进行的一些小优化,以及快读,(手动写了一下快读,大概懂了小型的快读原理)
代码:
#include <cstdio> #include <algorithm> using namespace std; typedef long long LL; int n,cnt; LL x[50005],y[50005],f[50005]; int que[50005]; struct node{LL x,y;}a[50005]; inline bool cmp(node a,node b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } inline double slop(int a,int b) { return (f[b]-f[a])*1.0/(y[a+1]-y[b+1]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lld%lld",&a[i].x,&a[i].y); } cnt=0; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++){ while(cnt&&a[i].y>=y[cnt])cnt--; x[++cnt]=a[i].x;y[cnt]=a[i].y; } // for(int i=1;i<=n;i++){ // printf("test %lld %lld\n",a[i].x,a[i].y); // } int l=0,r=0; for(int i=1;i<=cnt;i++){ while(l<r&&slop(que[l],que[l+1])<x[i])l++; int t=que[l]; f[i]=f[t]+y[t+1]*x[i]; while(l<r&&slop(que[r-1],que[r])>slop(que[r],i))r--; que[++r]=i; } printf("%lld\n",f[cnt]); return 0; }