Ihre Lösung ist auch ohne Swap nicht korrekt.
Test: [-1, 2, -1]. Ihre Antwort auf diesen Test ist -2. Richtige Antwort: -1
Ich hoffe, dass meine Lösung nicht die beste ist und es gibt einen besseren Ansatz.
Einfache O (N^3) Komplexitätslösung.
Nehmen wir an, dass unser endgültiges minimalen sequenziellen Segment wird [L, R] für einige 0 < = L < = R < N. Jetzt haben wir zwei multiset: A und B. A - multiset mit "inneren" Zahlen (Zahlen innerhalb des Bereichs [L, R]) und B - Multiset mit "äußeren" Zahlen (Zahlen außerhalb des Bereichs [L, R]). Ziel ist es, die Summe der Zahlen in A - Summe (A) zu minimieren. Swaping in A oder B ist sinnvoll, da es sich nicht auf die Summe (A) auswirkt. Wir können ein Element von A mit einem anderen Element in B austauschen. Wir haben nicht mehr als K Swaps und es bedeutet, dass nicht mehr als K Elemente in A mit nicht mehr als K Elementen in B getauscht werden. Um den Minimalwert der Summe zu erreichen (A) Wir nehmen einige maximale Elemente in A und tauschen sie mit minimalen Elementen in B aus. Zum Beispiel:
A = {-3, -3, -1, 2}; B = {-4, 1, 3, 6}; K = 2;
- Wir können 0 tauschen, A = {-3, -3, -1, 2}; B = {-4, 1, 3, 6}; dann sum (A) == -3
- Wir können 1 Tauschen machen, A = {-3, -3, -1, -4}; B = {2, 1, 3, 6}; dann sum (A) == -11
- Wir können 2 Tauschen machen, A = {-3, -3, 1, -4}; B = {2, -1, 3, 6}; Summe (A) dann == -9
Antwort ist die Summe (A) == -11
Für Bereich [L, R] können wir minimal mögliche Summe bekommen. Um eine Antwort für unser anfängliches Problem zu erhalten, werden wir über alle möglichen Bereiche iterieren [L, R]. 0 < = L < =
Naive Implementierung. O (N^3logn) Komplexität.
int get_minimum_contiguous_sum(vector <int> values, int k) {
int N = values.size();
int ans = values[0]; // initializing with any possible sums
for (int L = 0; L < N; L++) {
for (int R = L; R < N; R++) {
vector <int> A, B; // our "inner" and "outer" sets
int suma = 0; // will store initial sum of elements in A
for (int i = 0; i < N; i++) {
if (i >= L && i <= R) {
A.push_back(values[i]);
suma += values[i];
} else {
B.push_back(values[i]);
}
}
// Sorting set A in non-descending order
sort(A.begin(), A.end());
// Sorting set B in non-increasing order
sort(B.begin(), B.end());
reverse(B.begin(), B.end());
ans = min(ans, suma); // Updating answer with initial state
// Iterating number of swaps that we will make
for (int t = 1; t <= k; t++) {
// if some of two sets contain less than t elements
// then we cannot provide this number of swaps
if (t > A.size() || t > B.size()) break;
// Swapping t-th maximum of A with t-th minimum of B
// It means that t-th maximum of A subtracts from suma
// and t-th minimum of B added to suma
suma -= A[A.size() - t];
suma += B[B.size() - t];
ans = min(ans, suma);
}
}
}
return ans;
}
Optimierung
Lassen Sie uns davon ausgehen, dass für den Bereich [L, R] wissen wir bereits sortierte Menge A und Reverse B. sortierte Menge, wenn wir für den Bereich berechnen wird [L, R + 1] genau ein Element wird von B gelöscht und in A eingefügt (diese Zahl ist genau die Werte [R + 1]). C++ hat Container-Set und Multiset, die es uns erlauben, in O (Log) -Zeit einzufügen und zu entfernen und in O (n) -Zeit zu iterieren. Andere Programmiersprachen haben auch dieselben Container (in Java ist es TreeSet/SortedSet). Wenn wir also R nach R + 1 verschieben, werden wir einige einfache Anfragen an multiset (insert/remove) stellen.
O (N^3) -Lösung.
int get_minimum_contiguous_sum(vector <int> values, int k) {
int N = values.size();
int ans = values[0]; // initializing with any possible sums
for (int L = 0; L < N; L++) {
// "inner" multiset
// Stores in non-increasing order to iterate from beginning
multiset<int, greater<int> > A;
// "outer" multiset
// multiset by defaul stres in non-decreasing order
multiset<int> B;
// Initially all elements of array in B
for (int i = 0; i < N; i++) {
B.insert(values[i]);
}
int suma = 0; // Empty set has sum=0
for (int R = L; R < N; R++) {// Iterate over all possible R
// Removing element from B and inserting to A
B.erase(B.find(values[R]));
A.insert(values[R]);
suma += values[R];
ans = min(ans, suma);
__typeof(A.begin()) it_a = A.begin();
__typeof(B.begin()) it_b = B.begin();
int cur = suma;
for (int i = 1; i <= k; i++) {
if (it_a != A.end() && it_b != B.end())
break;
cur -= *it_a;
cur += *it_b;
ans = min(ans, cur);
it_a++;
it_b++;
}
}
}
return ans;
}
Hat die minimale sequenzielle Summe ohne Swap nicht einmal geben. –
Dieses Problem, oder eher eine vereinfachte Version, ist bekannt als das "Maximum-Subarray-Problem" https://en.wikipedia.org/wiki/Maximum_Subarray_Problem oder "die maximale Summe zusammenhängende Subsequenzproblem" http://wordaligned.org/articles/the-maximum-subsequence-Problem. Ich mag die zusätzliche Komplexität des Swappings. –
Können Sie ein konkretes Beispiel geben? – blazs