用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的复杂度。
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 90 3
Hints
#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 */