C. Baby Ehab Partitions Again
题意:给一串数字,问你最少删几个数能保证无论怎么把操作完的这串数分成两个子序列,两段的数字和都不一样。
首先sum如果是奇数,可以直接判输出0。
如果是sum偶数,我们只需要判断这些数找到构成和为sum/2的序列,dp判断(01背包)能不能有数字能凑出来sum/2,如果可以踹走一个奇数就行。但如果原序列一个奇数都没有,我们发现对这个序列同时除以2是不影响答案的,因为如果存在两个序列和相等, 那么对等式两边同时除以
2
2
2 不会有影响,因此我们一直除直到有一个数变成奇数,踹走这个数就行。因此我们证明了如果要删那最多删一个,删的那个一定是质因数分解后2次幂最低的那个数,因此我们读入的时候把这个数搞出来就行了。
code:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int n;
int a[N];
int f[N];
int Min = 0x3f3f3f3f, pos = 2;
int sum;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
sum += a[i];
int tmp = a[i], k = 0;
while(tmp % 2 == 0){
++k; tmp/=2;
}
if(k < Min) Min = k, pos = i;
}
if(sum & 1) cout << 0 << endl;
else
{
memset(f,0,sizeof(f));
f[0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = sum; j >= 0; --j)
if(f[j]) f[j + a[i]] = 1;
}
if(f[sum/2]) cout << 1 << "\n" << pos << endl;
else cout << 0 << endl;
}
return 0;
}