ZOJ 3331 Process the Tasks 双塔Dp

时间:2022-09-17 11:15:00
用dp[i][j]表示当前安排好了前i个任务,且机器A和机器B完成当前分配到的所有任务的时间差为j
(这里j可正可负,实现的时候需要加个offset)时,完成这些任务的最早时间。
然后根据j的正负,分别考虑任务i+1的两种分配方法。比如j大于0,A比B后空闲,
这个时候如果再把任务分配给A的话,B空闲知道A开始处理i+1的这段时间,B是不能安排任务的,
也就是说可以看成是非空闲的状态,于是下一个状态的A和B时间差就是i+1任务的长度。 就根据这个思路分几个情况进行处理,可以知道j这维不会超过100(就是上面这个原因),整个程序是100^2的复杂度。

  

Source Code:

//用dp[i][dt]表示当前安排好了前i个任务,且机器A和机器B完成当前分配到的所有任务的时间差为dt

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0) using namespace std; typedef long long ll ;
typedef unsigned long long ull ;
typedef unsigned int uint ;
typedef unsigned char uchar ; template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;} const double eps = 1e- ;
const int N = ;
const int M = * ;
const ll P = 10000000097ll ;
const int MAXN = ;
const int INF = 0x3f3f3f3f ;
const int offset = ; int dp[][], dt;
int ta[], tb[];
int n; int main () {
std::ios::sync_with_stdio (false);
int i, j, t, k, u, v, numCase = ;
cin >> t;
while (t--) {
cin >> n;
for (i = ; i <= n; ++i) {
cin >> ta[i] >> tb[i];
}
memset (dp, 0x3f, sizeof(dp));
dp[][ + offset] = ; for (i = ; i <= n; ++i) {
for (dt = -; dt <= ; ++dt) {
if (dp[i - ][dt + offset] == INF) continue; if (dt < ) { // B 机器人的工作时间更长
checkmin (dp[i][-tb[i] + offset], dp[i - ][dt + offset] + tb[i]); //放在B上面(继续由机器人B加工
checkmin (dp[i][dt + ta[i] + offset], dp[i - ][dt + offset] + Max(, ta[i] + dt));//放在A上面,继续让机器人A加工
} else { // A 机器人的工作时间更长
checkmin (dp[i][ta[i] + offset], dp[i - ][dt + offset] + ta[i]); //放在A上面,继续让机器人A加工
checkmin (dp[i][dt - tb[i] + offset], dp[i - ][dt + offset] + Max(, tb[i] - dt));//放在B上面,继续由机器人B加工
}
}
} int res = INF;
for(dt = -; dt <= ; ++dt){
checkmin (res, dp[n][dt + offset]);
}
cout << res << endl;
}
return ;
}