是道好题,卡常卡到我裂开/kk

题目链接

题目大意:有两台机器,共\(n\)个任务,每个任务你可以让第一台机器单独做花费它\(a\)时间,可以让第二台机器单独做花费它\(b\)时间,可以让两台机器同时做都花费\(c\)时间(部分任务有特殊要求,只能某些机器做),求完成所有任务最小时间

动态规划,奇奇怪怪的优化


分析:

首先题意有个不明确的地方(也可能是我没有读出来),就是时间\(c\)代表两台机器是分工做,而不是同时做,它们互不影响,也就是如果两台机器要共同完成一个任务,并不需要等到两台机器都空闲了,才能一起做

然后我们发现,当前的状态可以用一个三元组表示出来,\((i,a,b)\)表示已经做了前\(i\)个任务,第一台机器花费\(a\)时间,第二台机器花费\(b\)时间,总时间就是\(max(a,b)\),三元组的转移十分简单就不在此列出

空间不允许我们开三维数组,我们可以开二维,把\(i,a\)丢给下标表示,用数组值来表示\(c\),因为我们要求最小值,所以只需保存一个\(c\)最小的三元组即可

那么\(f[i][a]\)实际上表示已经做了前\(i\)个任务,第一台机器花费\(a\)时间的时候第二台机器最少花费的时间

转移方程:

\[f[i][a]=min\begin{cases}f[i-1][a-t_i.a] \\ f[i-1][a]+t_i.b \\ f[i-1][a-t_i.c]+t[i].c\end{cases} \]

\(t_i\)表示第\(i\)个任务,\(t_i.a\)表示给第一个机器做的时间(其他两个同理),转移条件略去qaq(主要是懒得打

这个朴素\(dp\)是跑不过去的,需要亿点点优化

  • 1.滚动数组消去第一维,使空间消耗变得可以接受,并且对连续空间的内存访问可以利用Cache大幅优化常数

  • 2.枚举上下界优化,我们记录一个最小的下界\(down\),表示\(down\)是最小的使\(f[i][down]\)状态存在的值。记录一个上界\(up\),显然\(up=\sum_{j=1}^i max(t_j.a,t_j.b,t_j.c)\)

  • 3.边读入边计算,原理同1

附上不开O2可以勉强卡过的代码:

#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn = 6033,maxm = 33333;
inline int read(){
	int x = 0;char c = getchar();
	while(!isdigit(c))c = getchar();
	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
	return x; 
}
inline int min(int a,int b){return a < b ? a : b;}
inline int max(int a,int b){return a > b ? a : b;} 
unsigned short f[maxm];
int n,ans = 0x7fffffff,down,up;
int main(){
	n = read();
	for(register int i = 1;i <= n;i++){
		int a = read(),b = read(),c = read(),beg = down;
		down = 0x7fffffff,up += max(a,max(b,c));
		for(register int j = up;j >= beg;j--){
			int tmp = 0x3f3f3f3f;
			if(a && j - a >= beg)tmp = min(tmp,f[j - a]);
			if(b)tmp = min(tmp,f[j] + b);
			if(c && j - c >= beg)tmp = min(tmp,f[j - c] + c);
			if(tmp < 0x3f3f3f3f)down = min(down,j);
			f[j] = tmp;
		}
	}
	for(int i = down;i <= up;i++)ans = min(ans,max(i,f[i]));
	printf("%d\n",ans);
	return 0;
}

相关文章:

  • 2021-07-02
  • 2022-03-03
  • 2021-10-13
  • 2021-11-10
  • 2021-06-13
  • 2022-03-07
  • 2021-12-30
  • 2021-09-26
猜你喜欢
  • 2021-07-02
  • 2022-01-24
  • 2021-07-29
  • 2021-09-11
  • 2021-07-22
  • 2022-03-05
  • 2021-07-19
相关资源
相似解决方案