zoukankan      html  css  js  c++  java
  • [BZOJ2726][SDOI2012]任务安排

    bzoj
    luogu(洛谷上面的是个(O(n^2))题)

    description

    (n)个任务,每次可以同时处理一段连续的任务,这些任务将同时处理完,且所需时间等于这些任务单独处理的总时间。每次处理任务前,机器需要(S)的时间准备。每个任务还有一个费用系数,这个任务的费用等于它的完成时刻乘上费用系数。求最小代价。
    (nle3 imes10^5)

    sol

    怎么(dp)算是一个难点了。
    直接计算当前这一次处理的所有任务的总代价,那就需要多记一维状态表示之前已经分了多少批。
    考虑在每次耗费时间的时候计算这段时间产生的费用,显然这段时间里尚未处理的任务都会产生相应的费用,而尚未处理的任务恰好是一段后缀。
    所以有(dp)式:

    [f_i=min{f_j+(t_i-t_j+S) imes(s_n-s_j)} ]

    其中(t,s)分别是时间和费用系数的前缀和。
    简单推导可知,当满足$$frac{(f_j-t_js_n+t_js_j-Ss_j)-(f_k-t_ks_n+t_ks_k-Ss_k)}{s_j-s_k}le t_i$$且(k<j)时,决策(j)优于决策(k)
    直接斜率优化即可。
    然后就发现(WA)了。为什么呢?因为时间有负数!(别问我怎么可能,也别问我怎么知道的)
    也就是说(t_i)不一定单调递增。
    但是貌似费用系数全是正的,也就是横坐标是满足单调增的,所以维护个下凸壳然后每次决策时二分即可。
    复杂度(O(nlog n))

    code

    被卡精度了。
    为什么弹栈的时候要加那个等于号啊,希望dalao们能教教我。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    ll gi(){
    	ll x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1e6+5;
    int n,top;ll S,t[N],s[N],f[N];
    struct node{int id;ll x,y;}q[N];
    ll getdp(int i,int j){
    	return f[j]+(t[i]-t[j]+S)*(s[n]-s[j]);
    }
    int main(){
    	n=gi();S=gi();
    	for (int i=1;i<=n;++i) t[i]=t[i-1]+gi(),s[i]=s[i-1]+gi();
    	for (int i=1;i<=n;++i){
    		int l=1,r=top,res=0;
    		while (l<=r){
    			int mid=l+r>>1;
    			if ((q[mid].y-q[mid-1].y)<1ll*t[i]*(q[mid].x-q[mid-1].x)) res=mid,l=mid+1;
    			else r=mid-1;
    		}
    		f[i]=getdp(i,q[res].id);
    		node tmp=(node){i,s[i],f[i]-s[n]*t[i]+s[i]*t[i]-s[i]*S};
    		while (top&&(q[top].y-q[top-1].y)*(tmp.x-q[top].x)>=(tmp.y-q[top].y)*(q[top].x-q[top-1].x)) --top;
    		q[++top]=tmp;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    uni-app开发经验分享九: 组件传值
    uni-app开发经验分享八: 实现微信APP支付的全过程详解
    CSS3+JS完美实现放大镜模式
    原生JS拖拽
    LeetCode 797. 所有可能的路径
    面试题 02.01. 移除重复节点
    LeetCode 139. 单词拆分
    LeetCode 1436. 旅行终点站
    LeetCode 16. 最接近的三数之和
    Hadoop 3.13在Ubuntu20.04上的单机伪分布式配置
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9267579.html
Copyright © 2011-2022 走看看