Thinking Process
Code
Greedy (Wrong Answer)
Time Complexity: , Space Complexity:
一開始寫的 Greedy 解法(Wrong Answer!),考慮以下的 case:
R = 3, 3, G = 4, B = 5,則 Greedy 會給出 20,但是答案應該是 27。所以說這題不行用 Greedy(只有兩個顏色的話當然可以),要用 DP。
#include<bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;
void run_case(){
int r, g ,b;
cin >> r >> g >> b;
vector<int> R(r);
vector<int> G(g);
vector<int> B(b);
for(int i = 0; i < r; i++) cin >> R[i];
for(int i = 0; i < g; i++) cin >> G[i];
for(int i = 0; i < b; i++) cin >> B[i];
sort(R.rbegin(), R.rend());
sort(G.rbegin(), G.rend());
sort(B.rbegin(), B.rend());
int i = 0, j = 0, k = 0;
ll res = 0;
// max heap
auto cmp = [](const pair<int, int>& p1, const pair<int, int>& p2) {return p1.first < p2.first;};
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pq(cmp);
pq.push({R[i++], 0});
pq.push({G[j++], 1});
pq.push({B[k++], 2});
while(!pq.empty()) {
pair<int, int> p1, p2;
if(!pq.empty()) {
p1 = pq.top(); pq.pop();
} else {
break;
}
if(!pq.empty()) {
p2 = pq.top(); pq.pop();
} else {
break;
}
res += 1LL * p1.first * p2.first;
if(p1.second == 0) {
if(i < r) pq.push({R[i++], 0});
} else if(p1.second == 1) {
if(j < g) pq.push({G[j++], 1});
} else if(p1.second == 2) {
if(k < b) pq.push({B[k++], 2});
}
if(p2.second == 0) {
if(i < r) pq.push({R[i++], 0});
} else if(p2.second == 1) {
if(j < g) pq.push({G[j++], 1});
} else if(p2.second == 2) {
if(k < b) pq.push({B[k++], 2});
}
}
cout << res << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(NULL);
int tests = 1;
// cin >> tests;
while(tests--){
run_case();
}
return 0;
}
DP
Time Complexity: , Space Complexity:
#include<bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;
void run_case(){
int r, g ,b;
cin >> r >> g >> b;
vector<int> R(r);
vector<int> G(g);
vector<int> B(b);
for(int i = 0; i < r; i++) cin >> R[i];
for(int i = 0; i < g; i++) cin >> G[i];
for(int i = 0; i < b; i++) cin >> B[i];
sort(R.rbegin(), R.rend());
sort(G.rbegin(), G.rend());
sort(B.rbegin(), B.rend());
ll res = 0;
vector<vector<vector<ll>>> dp(r + 1, vector<vector<ll>>(g + 1, vector<ll>(b + 1, 0)));
for(int i = 0; i <= r; i++) {
for(int j = 0; j <= g; j++) {
for(int k = 0; k <= b; k++) {
ll t = 0;
if(i != 0 && j != 0) t = max(t, dp[i - 1][j - 1][k] + R[i - 1] * G[j - 1]);
if(j != 0 && k != 0) t = max(t, dp[i][j - 1][k - 1] + G[j - 1] * B[k - 1]);
if(i != 0 && k != 0) t = max(t , dp[i - 1][j][k - 1] + R[i - 1] * B[k - 1]);
dp[i][j][k] = max(dp[i][j][k], t);
res = max(res, dp[i][j][k]);
}
}
}
cout << res << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(NULL);
int tests = 1;
// cin >> tests;
while(tests--){
run_case();
}
return 0;
}