Трудности в понимании логики сбалансированного разбиения

Я решал проблему сбалансированного разбиения по этой ссылке. В этом вопросе мы должны разделить массив на равные части так, чтобы разница между их суммой была наименьшей. Итак, решение, которое я нашел, заключается в рассмотрении всех случаев, независимо от того, будет ли элемент включен в одну группу или нет, означает, что мы должны попробовать все 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;
}

person skvatss    schedule 21.06.2016    source источник


Ответы (1)


Чтобы оптимизировать, вы можете попытаться суммировать первый и последний элемент каждого подмножества циклов и, таким образом, избегать циклирования всех элементов вашего подмножества, но циклически повторять только количество раз, равное половине размера вашего подмножества.

В вашем примере итерации внешнего цикла остаются прежними, а внутренние уменьшаются на 2:

(for(j=0; j<(N/2); j++)

и сумма ваших сгруппированных элементов подмножества:

v(1|2)+=(a[j] + a[N-j]);
person Ciro Corvino    schedule 21.06.2016