bzoj 1957 土地购买
这道题是我斜率优化第一题,对此做一个纪念。
首先进行一遍筛选,然后动态规划表达式很快就写出来了f(i)=min(f(i)+b[j+1]*a[i])
然后就要进行斜率优化了,显然这里边所有东西都是单调的,所以只需要维护单调队列即可。
cal函数计算的是斜率,具体看代码吧(参考别人),以后要多加练习。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 long long f[500005]; 6 int a[500005]; 7 int n; 8 long long u[50005],v[50005]; 9 struct node 10 { 11 long long x,y; 12 }p[50005]; 13 int q[50005]; 14 int head,tail; 15 bool cmp(int x,int y) 16 { 17 if(u[x]!=u[y])return u[x]<u[y]; 18 else return v[x]<v[y]; 19 } 20 int m; 21 double cal(int x,int y) 22 { 23 return (double)(f[y]-f[x])/(p[x+1].y-p[y+1].y); 24 } 25 int main() 26 { 27 scanf("%d",&n); 28 for(int i=1;i<=n;i++) 29 { 30 a[i]=i; 31 scanf("%lld%lld",&u[i],&v[i]); 32 } 33 sort(a+1,a+n+1,cmp); 34 for(int i=1;i<=n;i++) 35 { 36 while(m && p[m].y<=v[a[i]])m--; 37 m++; 38 p[m].x=u[a[i]]; 39 p[m].y=v[a[i]]; 40 } 41 n=m; 42 for(int i=1;i<=n;i++) 43 { 44 while(head<tail && cal(q[head],q[head+1])<p[i].x)head++; 45 int t=q[head]; 46 f[i]=f[t]+p[t+1].y*p[i].x; 47 while(head<tail && cal(q[tail-1],q[tail])>cal(q[tail],i))tail--; 48 q[++tail]=i; 49 } 50 printf("%lld\n",f[n]); 51 return 0; 52 } 53