Я решал проблему сбалансированного разделения от эта ссылка. В этом вопросе мы должны разделить массив на равные части так, чтобы разница между их суммами была наименьшей.
Итак, решение, которое я нашел, рассматривает все случаи, будет ли элемент включен в одну группу или нет, означает, что мы должны попробовать все 2 ^ n случаев.
Я пришел к решению, которое разделило массив с помощью битовых манипуляций, и я не понимаю логику.
Я публикую код ниже. Кто-то, пожалуйста, скажите мне, как он делит массив?
#include<bits/stdc++.h>
using namespace std;
#define N 11
void solve(int a[N])
{
long long x,y,v1,v2,res,i,j;
long long val=1<<N;
res=INT_MAX;
for(i=0;i<val;i++)
{
x=y=v1=v2=0;
for(j=0;j<N;j++)
{
if(i & (1<<j))
{
x++;
v1+=a[j];
}
else
{
y++;
v2+=a[j];
}
}
if(abs(x-y)<=1) res=min(res,abs(v1-v2));
}
cout<<res<<endl;
}
int main()
{
int a[] = {23, 45, -34, 12, 0, 98, -99, 4, 189, -1, 4};
solve(a);
return 0;
}
Для оптимизации вы можете попытаться суммировать первый и последний элемент каждого подмножества циклов, и, таким образом, избегать циклического обращения ко всем элементам номера вашего подмножества, но циклическое повторение только для количества раз равного половине размера вашего подмножества.
В вашем примере итерации внешнего цикла остаются прежними, а внутренние делятся на 2:
(for(j=0; j<(N/2); j++)
и сумма ваших сгруппированных элементов подмножества:
v(1|2)+=(a[j] + a[N-j]);
Других решений пока нет …