C++程式:計算使所有禮物數量相同的操作次數
假設我們有兩個陣列A和B,每個陣列的大小為n。有n份禮物,我們想把它們送給一些孩子。第i份禮物有A[i]顆糖果和B[i]個橙子。在一次移動中,我們可以選擇一些禮物並執行以下操作之一:
從這份禮物中取出恰好一顆糖果(如果可用);
從這份禮物中取出恰好一個橙子(如果可用);
從這份禮物中取出恰好一顆糖果和恰好一個橙子(如果可用)。
所有禮物都應該相等。這意味著在執行一系列移動後,以下兩個條件應該滿足:A[0] = A[1] = ... = A[n-1] 且 B[0] = B[1] = ... = B[n-1]。我們必須找到使所有禮物都相等所需的最小移動次數。
問題類別
上述問題可以透過應用貪心問題解決技術來解決。貪心演算法技術是一種演算法型別,其中選擇當前最佳解決方案,而不是遍歷所有可能的解決方案。貪心演算法技術也用於解決最佳化問題,就像它更大的兄弟動態規劃一樣。在動態規劃中,有必要遍歷所有可能的子問題以找出最優解,但它有一個缺點;它需要更多的時間和空間。因此,在各種情況下,使用貪心技術來找到問題的最優解。雖然它並非在所有情況下都能提供最優解,但如果設計得當,它可以比動態規劃問題更快地產生解決方案。貪心技術為最佳化問題提供區域性最優解。此技術的示例包括克魯斯卡爾和普里姆的最小生成樹 (MST) 演算法、霍夫曼樹編碼、迪傑斯特拉的單源最短路徑問題等。
https://tutorialspoint.tw/data_structures_algorithms/greedy_algorithms.htm
https://tutorialspoint.tw/data_structures_algorithms/dynamic_programming.htm
因此,如果我們問題的輸入類似於 A = [3, 5, 6];B = [3, 2, 3],則輸出將為 6,因為最初從 B 中取出,所以現在 B[0] 變為 [2, 2, 3],然後從 A[1] 中取出,所以 A = [3, 4, 6],然後再次從 A[1] 中取出,所以 A = [3, 3, 6],然後從 A[2] 和 B[2] 中取出,所以它們變為 [3, 3, 5] 和 [2, 2, 2],然後從 A[2] 中取出,所以它變為 A = [3, 3, 4],然後再次從 A[2] 中取出以使其變為 [3, 3, 3]。所以現在 A 具有相同數量的糖果,而 B 具有相同數量的橙子。
步驟
為了解決這個問題,我們將遵循以下步驟:
minA := inf minB := inf kq := 0 n := size of A for initialize i := 0, when i < n, update (increase i by 1), do: minA := minimum of minA and A[i] for initialize i := 0, when i < n, update (increase i by 1), do: minB := minimum of minB and B[i] for initialize i := 0, when i < n, update (increase i by 1), do: kq := kq + maximum of (A[i] - minA) and (B[i] - minB) return kq
示例
讓我們看看以下實現以獲得更好的理解:
#include <bits/stdc++.h>
using namespace std;
int solve(vector<int> A, vector<int> B){
int minA = 999, minB = 999, kq = 0;
int n = A.size();
for (int i = 0; i < n; i++)
minA = min(minA, A[i]);
for (int i = 0; i < n; i++)
minB = min(minB, B[i]);
for (int i = 0; i < n; i++)
kq += max(A[i] - minA, B[i] - minB);
return kq;
}
int main(){
vector<int> A = { 3, 5, 6 };
vector<int> B = { 3, 2, 3 };
cout << solve(A, B) << endl;
}輸入
{ 3, 5, 6 }, { 3, 2, 3 }輸出
6
資料結構
網路
RDBMS
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP