• 任务安排


    XII.任务安排

    斜率优化真\(\color{black}\colorbox{black}{XX}\)有意思!!

    \(t[i]\)表示原题中的\(t_i\)的前缀和,\(c[i]\)表示原题中\(f_i\)的前缀和,\(m\)表示启动时间\(s\)

    思路1:\(n^3\)DP:

    \(f[i][j]\)表示:前\(i\)个位置,分成\(j\)组,的最快时间。

    则有\(f[i][j]=\min\limits_{k=0}^{i-1}\{f[k][j-1]+(t[i]+m*j)*(c[i]-c[k])\}\)

    思路2:\(n^2\)DP:

    观察到我们每在第\(i\)个点前多分出一组,则在\(i\)后面所有东西的时间都会向后拖\(m\)时刻,共计造成\(m*(c[n]-c[i])\)点费用,

    因此我们可以设\(f[i]\)表示前\(i\)个位置的最短时间,

    则有\(f[i]=\min\limits_{j=0}^{i-1}\{f[j]+m*(c[n]-c[j])+t[i]*(c[i]-c[j])\}\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,f[10010],t[10010],c[10010];
    int main(){
    	scanf("%d%d",&n,&m),memset(f,0x3f3f3f3f,sizeof(f)),f[0]=0;
    	for(int i=1;i<=n;i++)scanf("%d%d",&t[i],&c[i]),t[i]+=t[i-1],c[i]+=c[i-1];
    	for(int i=1;i<=n;i++)for(int j=0;j<i;j++)f[i]=min(f[i],f[j]+m*(c[n]-c[j])+t[i]*(c[i]-c[j]));
    	printf("%d\n",f[n]);
    	return 0;
    }
    

    思路3:考虑斜率优化。

    \(j<k<i\),且\(j\)\(k\)更优。

    则有

    \(f[j]+m*(c[n]-c[j])+t[i]*(c[i]-c[j])<f[k]+m*(c[n]-c[k])+t[i]*(c[i]-c[k])\)

    拆括号

    \(f[j]+m*c[n]-m*c[j]+t[i]*c[i]-t[i]*c[j]<f[k]+m*c[n]-m*c[k]+t[i]*c[i]-t[i]*c[k]\)

    消元

    \(f[j]-m*c[j]-t[i]*c[j]<f[k]-m*c[k]-t[i]*c[k]\)

    移项并合并

    \(f[j]-f[k]-(m+t[i])*(c[j]-c[k])<0\)

    再移

    \(f[j]-f[k]<(m+t[i])*(c[j]-c[k])\)

    注意因为\(j<k\),且\(c\)是前缀和,则\(c[j]<c[k]\)。不等式两边除以负数,应该换方向。

    最终得到

    \(\dfrac{f[j]-f[k]}{c[j]-c[k]}>m+t[i]\)

    左边的东西仅与\(j\)\(k\)有关;右边的东西是单调的(\(t\)也是前缀和);

    因此就可以斜率优化辣。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,t[10100],c[10100],f[10100],q[10100],l,r;
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%d%d",&t[i],&c[i]),t[i]+=t[i-1],c[i]+=c[i-1];
    	for(int i=1;i<=n;i++){
    		while(r-l&&(f[q[l]]-f[q[l+1]])>=(c[q[l]]-c[q[l+1]])*(m+t[i]))l++;
    		f[i]=f[q[l]]+m*(c[n]-c[q[l]])+t[i]*(c[i]-c[q[l]]);
    		while(r-l&&(f[q[r-1]]-f[q[r]])*(c[q[r]]-c[i])>=(f[q[r]]-f[i])*(c[q[r-1]]-c[q[r]]))r--;
    		q[++r]=i;
    	}
    	printf("%d\n",f[n]);
    	return 0;
    }
    

  • 相关阅读:
    toString和equals两个比较常见的重写方式
    Java内构造函数、关键字、权限修饰符、访问控制及面向对象的特性!
    java中一个重要思想:面向对象
    JAVA基础汇总及例题详解
    java数据类型转换和数组总结
    java的数据基础
    HTML中的表格、表单元素与框架的构建
    linux命令学习(持续更新......)
    javascript bind在回调中精简匿名函数的用法
    CSS 文字超长省略显示并隐藏超长部分
  • 原文地址:https://www.cnblogs.com/Troverld/p/14596856.html
Copyright © 2020-2023  润新知