srm593 div1 450/div2 1000 MayTheBestPetWin

题目大意:

  给你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

标程在此:http://apps.topcoder.com/wiki/display/tc/SRM+593

原文地址:https://www.cnblogs.com/au-xiaotian/p/3358116.html