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;

}

 

你可能感兴趣的:(process)