题目大意:
给你n只动物,第 i 只动物完成一项任务需要花费的时间是A[i]至B[i]单位个时间,要求你将这n只动物分成两支队,竞赛。要求是两支队伍完成任务的时间差竟可能小,要你输出两支队伍完成任务最大的时间差maxdiff(S,T)。
分析:
设第 i 只动物完成任务的时间的上下限分别是B[i],A[i]; ΣB[i]=tB, ΣA[i]=tA;
假设已经分成了两个集合,S和T;设S集合完成任务的上下限分别是B(S),A(S),T集合B(T),A(T)那么maxdiff(S,T)=max(B(T)-A(S),B(S)-A(T));
因为A(S)=tA-A(T),B(S)=tB-B(T),因此上式可以写成maxdiff(S,T)=max(A(T)+B(T)-tA,tB-A(T)-B(T));
令s=A(T)+B(T); 上式可以写成maxdiff(S,T)=max(s-tA,tB-s);
方法:
dp,看了好久的标程,表示还是太RB了,哎。。。。
#include <iostream> #include <vector> #include <algorithm> #include <functional> #include <numeric> using namespace std; int tA,tB,A_plus_B[51]; //total A,B,A[i]+B[i]; tA+tB<=2*50*10000=1000000 int dp[1100000]; class MayTheBestPetWin { public: int calc(vector <int> A, vector <int> B) { tA=accumulate(A.begin(),A.end(),0); tB=accumulate(B.begin(),B.end(),0); for(int i=0;i<A.size();i++) A_plus_B[i]=A[i]+B[i]; for(int i=0;i<=1000000;i++) dp[i]=max(i-tA,tB-i); for(int ind=0;ind<A.size();ind++) { for(int s=0;s<=1000000;s++) { dp[s]=min(dp[s],dp[s+A_plus_B[ind]]); } } return pre[0]; } };
2013-10-08