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';
}
posted @ 2025-06-18 10:44  _Yxc  阅读(13)  评论(0)    收藏  举报