Istnieją dwie sekwencje całkowite A [] i B [] o długości N, obie nieposortowane.
Wymaganie: poprzez zamianę elementów między A [] i B [] (może losowo wymieniać, a nie z tym samym indeksem), dokonać różnicy między {sumą wszystkich elementów w A []} i {sumą wszystkich elementów w B [] } być minimum.
PS: Właściwie to jest pytanie z wywiadem, które spotkałem.
Wielkie dzięki
Odpowiedzi:
6 dla odpowiedzi № 1To będzie NP-trudne! Wierzę, że możesz zrobić redukcję Suma podzbioru do tego.
Zgodnie z komentarzami BlueRaja / polygene postaram się zapewnić pełną redukcję z sumy podzbioru.
Oto redukcja:
Problem z podzbiorem sumy: podane liczby całkowite x1, x2, ..., xn, czy istnieje jakiś niepusty podzbiór, który sumuje się do zera?
Nasz problem: Biorąc pod uwagę dwie liczby całkowite wielkości k, znajdź minimalną możliwą różnicę sumy dwóch tablic, zakładając, że możemy przetasować liczby całkowite w tablicach, traktując obie tablice jako jedną tablicę.
Powiedzmy, że dla naszego problemu mamy czas wielomianowy.
Powiedzmy, że otrzymałeś liczby całkowite T = {x1, x2, ..., xn} (multiset)
Niech Sja = x1 + x2 + ... + xn + xja.
Niech Tja = {x1, x2, ..., xi-1, xi + 1, ..., xn } (= T - xja)
Definiować
ZAja = Tablica utworzona za pomocą Tja
bja = [Sja, 0, ..., 0] (tzn. Jeden element to Sja a reszta to zera).
Niech mja = minimalna różnica znaleziona przez nasz problem dla tablic Aja oraz bja
(uruchamiamy nasz problem n razy).
Twierdzenie: Niektóre niepuste podzbiory T sumują się do zera wtedy i tylko wtedy, gdy jest jakiś element i, dla którego mja = 0.
Dowód: (wlog) powiedz x1 + x2 + .. + xk = 0
Następnie
A = [xk + 1, ..., xn, 0, ... 0]
B = [x2, x3, ..., xk, S1, 0, ..0]
daje minimalną różnicę m1 być | x2 + .. + xk + (x1 + ... + xn) + x1 - (xk + 1 + .. + xn) | = | 2 (x1+ x2 + .. xk) | = 0.
Podobnie można udowodnić część if.
Właściwie to również następuje (łatwiej) z partycji: po prostu utwórz nową tablicę ze wszystkimi zerami.
Ostrożnie nie popełniłem żadnych błędów.
3 dla odpowiedzi № 2
Weź dowolne wystąpienie NP-kompletne problem podziału:
Podziel multiset A dodatnich liczb całkowitych na dwie wielosety B i C z tą samą sumą
jak1,za2,...,zan}. Dodaj n zer {0,0,0 ..., 0, a1,...,zan} i zapytaj, czy zestaw można podzielić na dwa multisety A i B o tej samej sumie i takiej samej liczbie elementów. Twierdzę, że te dwa warunki są równoważne:
- Jeśli A i B są rozwiązaniem problemu, możesz usunąć zera i uzyskać rozwiązanie problemu partycji.
- Jeśli istnieje rozwiązanie problemu z partycją, na przykład ai1 + ai2 + ... aik = aj1 + ... + aJ l gdziei1, ai2, aik, aj1, ..., aJ l} = {a1, ..., an} to oczywiście k + l = n. Dodaj l zer po lewej stronie i k zer po prawej stronie, a otrzymasz 0 + ... + 0 + ai1 + ai2 + ... aik = 0 + ... + 0 + aj1 + ... + aJ l, który jest rozwiązaniem twojego problemu.
Jest to więc redukcja (więc problem jest NP-trudny), a problemem jest NP, więc jest NP-kompletny.
2 dla odpowiedzi nr 3
„sekwencje A [] i B [] o długości N” -> oznacza, że A i B są każdy o długości N?
(Dla jasności używam tablic opartych na 1).
Jeśli tak, to co powiesz na to:
- Załóżmy, że A [1..N] i B [1..N]
- Połącz A i B w nową tablicę C o długości 2N: C [1..N] <- A [1..N]; C [N + 1 .. 2N] <- B [1..N]
- Sortuj C w porządku rosnącym.
- Weź pierwszy para liczb z C; wyślij pierwszy element (C [1]) do A [1] i drugi element (C [2]) do B [1]
- Weź drugą parę liczb z C; tym razem wyślij druga element (C [4]) do A [2] i pierwszy element (C [3]) do B [2] (kolejność elementów w parze wysłanej do A i B jest przeciwna do 3)
- ... powtarzaj 3 i 4, aż skończy się C
Obserwacja tutaj jest taka, że w posortowanej tablicy,sąsiednia para liczb będzie miała najmniejszą różnicę (w porównaniu z parą liczb z pozycji niesąsiadujących). Krok 3 zapewnia, że A [1] i B [1] składają się z pary liczb o możliwie najmniejszej różnicy. Krok 4 zapewnia, że (a) A [2] i B [2] składają się z pary liczb o najmniejszej możliwej różnicy (z dostępnych liczb), a także (b) że różnica jest przeciwna w znaku z kroku 3. Przez kontynuując w ten sposób, zapewniamy, że A [i] i B [i] zawierają liczby z możliwie najmniejszą różnicą. Ponadto, odwracając kolejność, w jakiej wysyłamy elementy do A i B, zapewniamy, że różnica zmienia znak dla każdego kolejnego i.
1 dla odpowiedzi nr 4
Spróbuj być chciwym. Biorąc pod uwagę tak ograniczone informacje, nie jestem pewien, co jeszcze można tam umieścić.
0 dla odpowiedzi № 5
Nie jestem pewien, czy zapewni to minimalną możliwą odległość, ale pierwszą rzeczą, która przychodzi mi na myśl, jest coś takiego:
int diff=0;
for (int i = 0; i<len; i++){
int x = a[i] - b[i];
if (abs(diff - x) > abs(diff + x)){
swap(a,b,i);
diff-=x;
}else{
diff+=x;
}
}
zakładając, że masz funkcję wymiany, która pobiera dwie tablice i wymienia przedmioty na pozycji i :)
obliczanie i dodawanie różnicy między dwiema wartościami w pozycji i otrzymujesz przyrostową różnicę między sumami elementów dwóch tablic.
na każdym kroku sprawdzasz, czy lepiej jest dodać (a [i] -b [i]) lub (b [i] -a [i]). jeśli b [i] -a [i] to „s” W tym przypadku zamieniasz elementy na pozycji i w tablicach.
Może nie będzie to najlepszy sposób, ale powinien to być początek :)
0 dla odpowiedzi № 6
Problem jest NP-Complete.
Możemy zmniejszyć problem podziału do wersja decyzyjna tego problemu, tj. biorąc pod uwagę dwie tablice liczb całkowitych o tym samym rozmiarze, określ, czy elementy można zamienić, aby sumy były równe.
Wejście do problemu partycji: zestaw S liczb całkowitych, o rozmiarze N
Aby przekształcić to wejście w wejście donasz problem, definiujemy A jako tablicę wszystkich elementów w S, a B tablicę o tym samym rozmiarze, z B [i] = 0 dla wszystkich i. Ta transformacja jest liniowa w wielkości wejściowej.
Oczywiste jest, że nasz algorytm zastosowany w A i B zwraca wartość true wtedy i tylko wtedy, gdy istnieje podział S na 2 podzbiory, tak że sumy są równe.