首页 > 其他分享 >[P5785 [SDOI2012]任务安排] 题解

[P5785 [SDOI2012]任务安排] 题解

时间:2023-05-01 10:24:42浏览次数:56  
标签:P5785 le 题解 tail SDOI2012 maxn sumc dp dq

P5785 [SDOI2012]任务安排

题目描述

分析

很明显是一个dp
我们不妨设\(dp[i]\)表示枚举到\(i\)的最小费用
\(t[i]\)表示加工完第\(i\)个任务所用的总时间,也就是\(T[i]\)的前缀和
由于每一批任务前都要一个时间为\(s\)的开机工作
我们不妨把每一个这样的\(s\)秒提出来,则这\(s\)秒都会对后面所有的\(c[i]\)产生影响
\(dp[i]= \min(dp[j]+s * \sum_{k=j+1}^{k \le n}{c[k]}+t[i] * \sum_{k=j+1}^{k \le i}{c[k]})\)
我们再用\(sumc[i]\)表示\(c\)数组的前缀和
那么
\(dp[i]=\min(dp[j]+s * (sumc[n]-sumc[j])+t[i] * (sumc[i]-sumc[j]) )\)
设\(F[i]=s * (sumc[n]-sumc[i])\),\(G[i]=t[i]* sumc[i]\)
则\(dp[i]=\min(dp[j]+F[j]+G[i]-t[i]* sumc[j])\)
\(dp[i]=\min(dp[j]+F[j]-t[i]* sumc[j])+G[i]\)
这就是一个可以用斜率优化的dp方程式了

斜率优化
  1. 设两个决策点\(j_1,j_2(j_2>j_1)\),\(j_2\)优于\(j_1\)
    注意此时\(sumc[j_2]>sumc[j_1]\),那么在后续的化简中,遇到负数要变号
    \(dp[j_1]+F[j_1]-t[i]* sumc[j_1] \ge dp[j_2]+F[j_2]-t[i]* sumc[j_2]\)
  2. 拆开不等式
    \((dp[j_1]+F[j_1])-(dp[j_2]+F[j_2) \ge t[i]* (sumc[j_1]-sumc[j_2])\)
    注意这里的\(sumc[j_1]-sumc[j_2] \lt 0\),所以下一步需要变号
    \(\frac{(dp[j_1]+F[j_1])-(dp[j_2]+F[j_2])}{sumc[j_1]-sumc[j_2]} \le t[i]\)
    \(\frac{(dp[j_2]+F[j_2])-(dp[j_1]+F[j_1])}{sumc[j_2]-sumc[j_1]} \le t[i]\)
    还可以再把\(F[i]\)代入进行化简
    \(\frac{dp[j_2]}{sumc[j_2]-sumc[j_1]} \le t[i]+s\)

斜率就这样推出来啦!
注意题目中\(T[i]\)是有可能为负数的,所以\(t[i]\)不是单调递增的
所以我们就不能随意把队首元素删除,而在找队首时只能用二分

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long 

const int maxn=3e5+10;
int n,head,tail;
ll s,T[maxn],t[maxn],c[maxn],sumc[maxn];
ll G[maxn],dp[maxn];
int dq[maxn*2];

int find(ll x){
  if(head==tail) return head;
  int l=head,r=tail;
  while(l<r){
    int mid=(l+r)>>1;
    if(dp[dq[mid+1]]-dp[dq[mid]]<=(x+s)*(sumc[dq[mid+1]]-sumc[dq[mid]])) l=mid+1;
    else r=mid;
  }
  return l;
}

int main(){
  /*2023.5.1 hewanying P5785 [SDOI2012]任务安排 斜率优化dp*/ 
  scanf("%d%lld",&n,&s);
  for(int i=1;i<=n;i++){
  	scanf("%lld%lld",&T[i],&c[i]);
  	sumc[i]=sumc[i-1]+c[i];
  	t[i]=t[i-1]+T[i];
  	G[i]=t[i]*sumc[i];
  }
  memset(dp,0x3f,sizeof(dp));dp[0]=0;
  for(int i=1;i<=n;i++){
  	int op=find(t[i]);
  	dp[i]=dp[dq[op]]+s*(sumc[n]-sumc[dq[op]])-t[i]*sumc[dq[op]]+G[i];
  	while(head<tail&&(dp[dq[tail]]-dp[dq[tail-1]])*(sumc[i]-sumc[dq[tail]])>=(dp[i]-dp[dq[tail]])*(sumc[dq[tail]]-sumc[dq[tail-1]])) 
	  tail--; //这个地方必须要取>=在=时不用压入队中,否则会影响二分的进行,二分涉及相等的问题 
  	dq[++tail]=i;
  }
  printf("%lld\n",dp[n]);
  return 0;
}

总结

  1. 斜率优化还是存在精度问题,这道题就有两斜率相等的情况,所以直接变除为乘
  2. 在\(t[i]\)递增时才能用双端队列直接把队首删去,而这道题数组中存在负数,就只有用二分来计算
  3. 在dp开始前,不用加\(dq[++tail]=0\),因为初始化中\(dq[0]=0\),这样一来dq中就有两个0了
  4. 在删除队尾时,两斜率相等也是不满足条件的,所以要用\(>=\)
    如果等于没有排除,会影响二分的进行

标签:P5785,le,题解,tail,SDOI2012,maxn,sumc,dp,dq
From: https://www.cnblogs.com/hewanying0622/p/17366211.html

相关文章

  • CF1624G 题解
    前言题目传送门!更好的阅读体验?比较好玩的二进制题目。思路答案最小,也就是说较高位要尽可能小。所以很容易想到从最高位开始枚举。第\(i\)位为\(0\),等价于选出的所有边的第\(i\)位都为\(0\)。同时,由于我们是贪心,如果之前枚举过的第\(j\)位可以是\(0\),那么这两个条件......
  • 洛谷 P7579 「RdOI R2」称重(weigh) 题解
    题意:题目一道交互题。有n个球,里面有两个假球,假球比普通球的要轻,每次可以询问任意两组球的轻重关系,第一组轻为<,第二组轻为>,一样重量为=。思路:先考虑在一个区间内找1个假球。我们可以将区间尽量平均分为3份,先询问相等的两组球的轻重关系,分3种情况:第一组轻......
  • 【题解】CF44G Shooting Gallery
    题目大意给定\(n\)个三维空间的平面,由高度\(z\)、\(x\)的范围\([xl,xr]\)和\(y\)的范围\([yl,yr]\)来表示。有\(m\)次射击,每次射击点\((x,y)\),摧毁包含此点的\(z\)值最小的平面,输出此平面编号,若摧毁不了任何平面,输出\(0\)。题解点查平面不好做,于是可以转化为平面查点,先将平面按......
  • Codeforces Round 869 (Div.1 & Div.2) 题解
    2A.Politics因为编号为\(1\)的人一定不会离开,那么最后留下的人一定要和编号为\(1\)的人的所有参数都一致,所以计数即可。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>u......
  • CF51F Caterpillar题解
    题目传送门题意:定义毛毛虫为一种特殊的树,形如一条链上挂着若干个叶子。特殊地,在本题中的毛毛虫允许自环但不允许重边。给定一个无向图,每次操作可以合并两个点以及两个点的出边(两个点有相同出边则出现重边,两个点之间有边则出现自环)。求将其变为毛毛虫的最小操作次数。容易发现,......
  • Windows下安装Docker详细过程及问题解决
    官方手册供参考:https://docs.docker.com/desktop/windows/一:什么是Docker?Docker是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。Dock......
  • 义中常规赛430题解
    T1二分一个删除的数字个数然后考虑删除的数字肯定是从大到小来的,所以预处理一个降序的数组,这样能知道二分的数字个数所对应的数字。在原数组上跑最大子段和,如果碰到大于二分位置的数字就删了。最终成绩26分,因为对于二分的个数mid,原数组中a[mid]不止1个的话,无法判断哪些该删,哪......
  • Android Bitmap内存溢出问题解释
    Android平台在图片处理方面经常会出现OOM的问题,在去年开发的一个项目中,我也一直被这个问题所困扰,在这方面也搜集了许多的资料,今天仅仅针对Android平台的Bitmap说事儿,今后再对内存的问题做详细的探讨,android平台对图片解码这块确实设置的有内存上限,在解码Bitmap的时候android平台会......
  • abc252_d Distinct Trio 题解
    这是数学题耶!题意给定一个整数\(n\)和一个长度为\(n\)的整数序列\(a\),求满足以下要求的三元组个数:\(1\leqslanti<j<k\leqslantn\)。\(a_i\nea_j\),\(a_j\nea_k\),\(a_k\nea_i\)。思路先想正着做,好,不会。正着做不行就反着做,先算出所有情况,再去掉不合法。......
  • ABC G Ex 简要题解
    ABC212GPowerPair推柿子题\(\sum\limits_{x}^{P-1}\sum\limits_{y}^{P-1}\existsn\in\mathbb{N}\x^n\equivy(\bmodP)\)\(1+\sum\limits_{x=1}^{P-1}\sum\limits_{y=1}^{P-1}\existsn\in\mathbb{N}\x^n\equivy(\bmodP)\)考虑模\(P\)......