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;
    }
    
  • 相关阅读:
    javaweb消息中间件——rabbitmq入门
    virtual box 桥接模式(bridge adapter)下无法获取ip(determine ip failed)的解决方法
    Apache Kylin本地启动
    git操作
    Java学习总结
    Java中同步的几种实现方式
    hibernate exception nested transactions not supported 解决方法
    vue 中解决移动端使用 js sdk 在ios 上一直报invalid signature 的问题解决
    cookie 的使用
    vue 专门为了解决修改微信标题而生的项目
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9267579.html
Copyright © 2011-2022 走看看