最小的反例金额是多少
面值 4、3、1,金额从 1 往上试,找第一个贪心比最优多花枚数的金额。
运行下面这段程序:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int greedy(const vector<int>& cs, int t) {
// 面值已按从大到小给好:每次拿不超过剩下金额的最大面值
int n = 0;
for (int c : cs) {
while (t >= c) {
t -= c;
n++;
}
}
return n;
}
int best(const vector<int>& cs, int t) {
// dp[a] = 凑够 a 最少要几枚
const int INF = 1000000000;
vector<int> dp(t + 1, INF);
dp[0] = 0;
for (int a = 1; a <= t; a++) {
for (int c : cs) {
if (c <= a && dp[a - c] + 1 < dp[a]) dp[a] = dp[a - c] + 1;
}
}
return dp[t];
}
int main() {
int a = 1;
while (greedy({4, 3, 1}, a) == best({4, 3, 1}, a)) a++;
cout << a << endl;
}
(本题用 g++ -std=c++17 -O0 编译。)