用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-7 ; const int N = 210 ; const int M = 1100011*2 ; const ll P = 10000000097ll ; const int MAXN = 10900000 ; const int INF = 0x3f3f3f3f ; const int offset = 100 ; int dp[100][200], dt; int ta[100], tb[100]; int n; int main () { std::ios::sync_with_stdio (false); int i, j, t, k, u, v, numCase = 0; cin >> t; while (t--) { cin >> n; for (i = 1; i <= n; ++i) { cin >> ta[i] >> tb[i]; } memset (dp, 0x3f, sizeof(dp)); dp[0][0 + offset] = 0; for (i = 1; i <= n; ++i) { for (dt = -99; dt <= 99; ++dt) { if (dp[i - 1][dt + offset] == INF) continue; if (dt < 0) { // B 机器人的工作时间更长 checkmin (dp[i][-tb[i] + offset], dp[i - 1][dt + offset] + tb[i]); //放在B上面(继续由机器人B加工 checkmin (dp[i][dt + ta[i] + offset], dp[i - 1][dt + offset] + Max(0, ta[i] + dt));//放在A上面,继续让机器人A加工 } else { // A 机器人的工作时间更长 checkmin (dp[i][ta[i] + offset], dp[i - 1][dt + offset] + ta[i]); //放在A上面,继续让机器人A加工 checkmin (dp[i][dt - tb[i] + offset], dp[i - 1][dt + offset] + Max(0, tb[i] - dt));//放在B上面,继续由机器人B加工 } } } int res = INF; for(dt = -99; dt <= 99; ++dt){ checkmin (res, dp[n][dt + offset]); } cout << res << endl; } return 0; }