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. 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 integerstA, 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 90 3
Hints
代码里是从 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; }