Processing math: 100%

MayTheBestPetWin

SRM593 Div1Medium

Posted by Songtoy on 2017-05-04

我们要求的是max{S1BS2A,S2BS1A}的最小值,很难直接DP,因为无法知道当前元素对答案的贡献,因为最终的答案是取max的,无法再过程中取得最优值,需要考虑每个元素对答案的贡献.

  • 如果当前元素放到集合S1 ,其对左边和的贡献是A
  • 如果当前元素放到集合S2 ,其对左边和的贡献是B

因此当前元素对左边和的贡献来回相差A+B ,其实
S1BS2A=S1B+S2B(S2A+S2B)
=BS2(A+B)
同理右边和即为
BS1(A+B)=B((A+B)S2(A+B))
=S2(A+B)A
因此答案即为max{BS2(A+B),S2(A+B)A}
直接Dp求出所有可行的S2(A+B)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MayTheBestPetWin {
public:
static const int M = 100*10000+5;
bitset<M>cnt;
void Chk(int &a,int b){
if(a==-1||a>b)a=b;
}
int calc(vector <int> A, vector <int> B) {
int n=A.size();
cnt.set(0);
for(int i=0;i<n;++i){
cnt|=cnt<<(A[i]+B[i]);
}
int sumA=0,sumB=0,ans=-1;
for(int i=0;i<n;++i)sumA+=A[i],sumB+=B[i];
for(int i=0;i<M;++i){
if(cnt[i])Chk(ans,max(abs(sumA-i),abs(sumB-i)));
}
return ans;
}
};