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;
}

该博客探讨了一种算法问题,即如何在最少删除数字的情况下,确保一个数字序列无论如何划分成两个子序列,它们的和都不相同。当序列总和为奇数时,直接返回0;若为偶数,则通过动态规划判断是否能构造和为总和一半的序列,如果可以,只需移除一个奇数;若序列中没有奇数,可以通过将所有数除以2直至出现奇数并移除。代码实现使用C++,包括动态规划和01背包策略。
1238

被折叠的 条评论
为什么被折叠?



