• BZOJ1597 [Usaco2008 Mar]土地购买


    斜率优化dp。
    显然,如果一个土地的长,宽都小于另一个土地,那么就一定能被免费打包带走,排个序(或许只有我因为这个调了半天),去一下这些没用的。
    一个(O(n^2))的显然做法:以f[i]表示买了前i块土地最小花费。
    (f_i=f_j+len_i cdot width_{j+1} (1<=j<=i))
    然后转化一下式子,弄成(-f_j=len_i cdot width_{j+1}-f_i),就成了斜率优化的形式,维护一个下凸包即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    const int N=50005;
    struct TD {
    	int len,width;
    } t[N],d[N];
    int n;
    int q[N<<2],l,r,cnt,f[N];
    bool cmp(TD x,TD y) {
    	return x.width>y.width||(x.width==y.width&&x.len>y.len);
    }
    double slope(int x,int y) {
    	return (double)(-f[x]+f[y])/(double)(d[1+x].width-d[y+1].width);
    }
    main() {
    	scanf("%lld",&n);
    	for(int i=1; i<=n; i++)
    		scanf("%lld%lld",&t[i].width,&t[i].len);
    	sort(t+1,t+1+n,cmp);
    	for(int i=1; i<=n; i++) {
    		if(t[i].len>d[cnt].len) d[++cnt]=t[i];
    	}
    	n=cnt;
    	for(int i=1; i<=n; i++) {
    		while(l<r&&slope(q[l],q[l+1])<=d[i].len) l++;
    		f[i]=f[q[l]]+d[i].len*d[q[l]+1].width;
    		while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i))r--;
    		q[++r]=i;
    	}
    	cout<<f[n];
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    JavaScript的学习----2.操作BOM对象
    Maven的配置和Eclipse中导入SpringBoot项目一些注意点
    JavaScript学习----1.基础篇
    线程池的学习
    CSS的初步学习
    类的加载细节探索
    反射与注解
    数据结构第二章
    数据结构第一章
    用结构和STL常用算法实现对学生成绩的排序和查找(vector)
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9347942.html
Copyright © 2020-2023  润新知