zoj 3331 Process the Tasks(双塔DP)

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. ThenT test cases follow. Each test case starts with an integer n (0 < n < 100). The ith line of the next n lines contains two integerstAtB (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.

代码里是从 dp[i-1][j] 开始做状态转移的
就比如前面 j<= 100 的那个部分吧,
如果把任务给 A 做,两个机器的时间差就会变成 j + ta[i]
如果把任务给 B 做,因为 j <= 100 表示 B 正在处理一个任务,所以必须先等待那个任务做完(j 回到 100),然后再给 B(再从 100 变到 100 - tb[i])

j里面+100的原因是为了不让下标取到负

#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
int dp[201][201],ta[101],tb[101],ans;
void init(void)  //双塔DP(本题取值1-100) 
{  
    int i,j;  
    for(i=0;i<201;i++){
        for(j=0;j<201;j++){
			dp[i][j]=100000000;  
		}
	}
    dp[0][100]=0;  //初始状态 
    ans=100000000;  
}
int main(void)  
{  
    int T,n,i,d,j;  
    scanf("%d",&T);  
    while(T--)  
    {  
        init();  
        scanf("%d",&n);  
        for(i=1;i<=n;i++)  
            scanf("%d%d",&ta[i],&tb[i]);  
        for(i=1;i<=n;i++)  
            for(j=0;j<=200;j++)  
            if(dp[i-1][j]!=100000000)  
            {  
                if(j<=100)  //b比a高
                {  
                    dp[i][100-tb[i]]=min(dp[i][100-tb[i]],dp[i-1][j]+tb[i]);  
                    dp[i][j+ta[i]]=min(dp[i][j+ta[i]],dp[i-1][j]+max(0,j-100+ta[i]));  
                }  
                else  //a比b高
                {  
                    dp[i][100+ta[i]]=min(dp[i][100+ta[i]],dp[i-1][j]+ta[i]);  
                    dp[i][j-tb[i]]=min(dp[i][j-tb[i]],dp[i-1][j]+max(0,tb[i]-(j-100)));  
                }  
            }  
            for(i=0;i<200;i++)
                ans=min(ans,dp[n][i]); //找出值最小的一个状态 
            printf("%d\n",ans);  
    }  
    return 0;  
}  


你可能感兴趣的:(zoj 3331 Process the Tasks(双塔DP))