ZOJ 3331 Process the Tasks 双塔Dp

用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;
}
原文地址:https://www.cnblogs.com/wushuaiyi/p/4340276.html