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 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 tA, tB (0 < tA, tB < 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 903
双塔DP
dp[i][j] 表示执行第i个任务,机器A和机器B的时间差
双塔DP 顾名思义可以把A机器和B机器看作是两座塔,如果把当前任务放在哪个塔上,那么哪个塔的高度就会增加
每次放任务,都会有两个选择,要么放在A塔,要么放在B塔。如果放在高的塔上,根据题意在同一个机器上必要上一个任务完成
时才能进行下一个任务,所以等高的塔完成上一个任务是,A,B都是空闲的了,这个是在高的塔上放任务,时间差就是这个任务的时间
如果放在低的塔上,那么在之前的差值上加上这个任务的时间
#include <iostream> #include <string.h> #include <stdlib.h> #include <math.h> #include <stdio.h> using namespace std; #define MAX 10000000 int dp[105][205]; int n; int ta[105]; int tb[105]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&ta[i],&tb[i]); for(int i=0;i<=n;i++) for(int j=0;j<=200;j++) dp[i][j]=MAX; dp[0][0+100]=0; for(int i=1;i<=n;i++) { for(int j=-99;j<=99;j++) { if(dp[i-1][j+100]==MAX) continue; if(j<0) { dp[i][-tb[i]+100]=min(dp[i][-tb[i]+100],dp[i-1][j+100]+tb[i]); dp[i][j+ta[i]+100]=min(dp[i][j+ta[i]+100],dp[i-1][j+100]+max(0,j+ta[i])); } else { dp[i][ta[i]+100]=min(dp[i][ta[i]+100],dp[i-1][j+100]+ta[i]); dp[i][j-tb[i]+100]=min(dp[i][j-tb[i]+100],dp[i-1][j+100]+max(0,tb[i]-j)); } } } int ans=MAX; for(int i=-99;i<=99;i++) ans=min(ans,dp[n][i+100]); printf("%d\n",ans); } return 0; }