D. Make Them Equal
https://codeforces.com/problemset/problem/1633/D
题意:给定长度为n的数组a,b,c和数字k。a初始全为1。现问不超过k次操作,可以获得的最大代价是多少?如果a[i]通过操作跟b[i]相等,那么可以获得c[i]的代价。 操作:选定一个下标i与数字x,a[i] += a[i] / x;
思路:先求出1变成b中各个数字的最小操作数,然后动态规划依次考虑将b[i]添加到当前维护的集合中,最后取操作数不超过k的最优解即可。
总结:一开始求最小操作数的时候,用了动态规划,应该用bfs的,这个就是最短路径问题,数据范围也不大,bfs更好理解。后面做动态规划的时候,要用红黑树,不然状态集过大应该会TLE。
constexpr int N = 1e3 + 10;
constexpr int inf = 0x3f3f3f3f;
vector<int> dp(N, inf);
inline void preProcess() {
dp[1] = 0;
queue<int> q;
q.push(1);
while (!q.empty()) {
int cur = q.front(); q.pop();
for (int x = 1; x <= cur; ++x) {
int nxt = cur + cur / x;
if (nxt >= N) continue;
if (dp[nxt] > dp[cur] + 1) {
dp[nxt] = dp[cur] + 1;
q.push(nxt);
}
}
}
}
inline void solve() {
int n, k;
cin >> n >> k;
vector<int> b(n), c(n);
for (int i = 0; i < n; ++i) {
cin >> b[i];
}
for (int i = 0; i < n; ++i) {
cin >> c[i];
}
map<int, int> mapp;
mapp[0] = 0;
int ans = 0;
for (int i = 0; i < n; ++i) {
auto temp = mapp;
for (auto[x, y] : temp) {
int need = dp[b[i]];
mapp[x + need] = max(mapp[x + need], y + c[i]);
if (x + need <= k) {
ans = max(ans, mapp[x + need]);
}
}
}
cout << ans << '\n';
}

浙公网安备 33010602011771号