ZOJ 3331 Process the Tasks

用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的复杂度。

Process the Tasks Time Limit: 1 Second       Memory Limit: 32768 KB

There are two machines A and B. There are n tasks, namely task 1, task 2, ..., task n. You must assign each task to one machine to process it. There are some facts you must know and comply with:

  • You must assign each task to only one machine to process.
  • At any time, a machine can process at most one task.
  • Task i (0 < i < n) can be processed if and only if each task j (0 < j < i) has been processed or processing.
  • If a task is processing on one machine, it cannot be interrupted.

You want to do finish all the tasks as soon as possible.

Input

There are multiple test cases. The first line of the input is an integer T (0 < T < 1000) indicating the number of test cases. Then T test cases follow. Each test case starts with an integer n (0 < n < 100). The ith line of the next n lines contains two integers tAtB (0 < tAtB < 100), giving the time to process the ith task by machine A and machine B.

Output

For each test case, output the earliest time when all the tasks have been processed.

Sample Input

4
1
1 2
2
1 2
2 1
2
1 2
90 95
3
1 3
1 3
1 3

Sample Output

1
1
90
3

Hints

  • Test case 1: Let machine A process task 1.
  • Test case 2: Let machine A process task 1 and at the same time let machine B process task 2.
  • Test case 3: Let machine B process task 1 and at the same time let machine A process task 2.
  • Test case 4: Let machine A process all the tasks.
Author:  CAO, Peng
Source:  The 7th Zhejiang Provincial Collegiate Programming Contest


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

const int offset=100;

int f[222][222];
int a[333][2];
#define dp(i,j) f[i][(j)+offset]
int n;
void Min(int &a,int b) { a=min(a,b); }
int main()
{
    int re; cin>>re; int ca=1;
    while(re--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i][0]>>a[i][1];
        memset(f,63,sizeof f);
        dp(0,0)=0;
        for(int i=0;i<n;i++)
        {
            for(int j=-offset;j<=offset;j++)
            {
                if(j>=0)
                {
                    Min(dp(i+1,a[i+1][0]),dp(i,j)+a[i+1][0]);
                    Min(dp(i+1,j-a[i+1][1]),max(dp(i,j)-j+a[i+1][1],dp(i,j)));
                }
                if(j<0)
                {
                    Min(dp(i+1,a[i+1][0]+j),max(dp(i,j),dp(i,j)+j+a[i+1][0]));
                    Min(dp(i+1,-a[i+1][1]),dp(i,j)+a[i+1][1]);
                }
            }
        }
        int ans=1e9;
        for(int i=-offset;i<=offset;i++) ans=min(ans,dp(n,i));
        cout<<ans<<endl;
    }
}
/**
99
1
1 2
2
1 2
2 1
2
1 2
90 95
3
1 3
1 3
1 3
4
1 3
1 3
1 8
1 8

*/


你可能感兴趣的:(ZOJ 3331 Process the Tasks)