思路一:贪心
具体思路:尽量让产生0最晚,这样就一直有正整数可以选,因此每次选最大的两个
class Solution {
public:
int fillCups(vector<int>& amount) {
priority_queue<int> pq;
for (int i = 0; i < 3; ++i) {
if (amount[i]) pq.push(amount[i]);
}
int ans = 0;
while (!pq.empty()) {
ans++;
if (pq.size() >= 2) {
int a = pq.top();
pq.pop();
int b = pq.top();
pq.pop();
if (--a) pq.push(a);
if (--b) pq.push(b);
}else {
int a = pq.top();
pq.pop();
if (--a) pq.push(a);
}
}
return ans;
}
};
思路二:数学思想
class Solution {
public:
int fillCups(vector<int>& amount) {
sort(amount.begin(), amount.end());
if (amount[0] + amount[1] <= amount[2]) return amount[2];
return (amount[0] + amount[1] + amount[2] + 1) / 2;
}
};
思路三:暴力dfs+记忆化+字符串hash
unordered_map<long long, int> cache; //
class Solution {
public:
const long long base = 131;
int dfs(vector<int>& amount) {
if (*max_element(amount.begin(), amount.end()) == 0) {
return 0;
}
long long tmp2 = base * base * amount[0] + base * amount[1] + amount[2];
if (cache.count(tmp2))
return cache[tmp2];
int ans = INT_MAX;
if (amount[0] > 0 && amount[1] > 0) { //
amount[0]--;
amount[1]--;
ans = min(ans, dfs(amount)+1);
amount[0]++;
amount[1]++;
}
if (amount[0] > 0 && amount[2] > 0) {
amount[0]--;
amount[2]--;
ans = min(ans, dfs(amount)+1);
amount[0]++;
amount[2]++;
}
if (amount[2] > 0 && amount[1] > 0) {
amount[2]--;
amount[1]--;
ans = min(ans, dfs(amount)+1);
amount[2]++;
amount[1]++;
}
if (amount[0] > 0) {
amount[0]--;
ans = min(ans, dfs(amount)+1);
amount[0]++;
}
if (amount[1] > 0) {
amount[1]--;
ans = min(ans, dfs(amount)+1);
amount[1]++;
}
if (amount[2] > 0) {
amount[2]--;
ans = min(ans, dfs(amount)+1);
amount[2]++;
}
return cache[tmp2] = ans;
}
int fillCups(vector<int>& amount) {
int ans = dfs(amount);
return ans;
}
};
需要注意的两个地方:
1:unordered_map<long long, int> cache; 放到class类外能过,放到类内过不了。
放到类外cache是所有测试用例共享的,放到类内每个用力都得执行一遍,因此速度会更快。
2:
cache[key] = min(cache[key], dfs({amount[0] - 1, amount[1] - 1, amount[2]}) + 1);
如果用上面写法的话,发生超时,参数可以优化下:还是使用amount,避免产生临时的vector
if (amount[0] > 0 && amount[1] > 0) { //
amount[0]--;
amount[1]--;
ans = min(ans, dfs(amount)+1);
amount[0]++;
amount[1]++;
}