20230417 训练记录:dp

你也许会好奇为什么没有 04.16 的训练记录,昨天农了一天 O(∩_∩)O。

Vacation#

小明在接下来的 n 天,可以选择三种事件并获得 ai/bi/ci 的快乐值,但是他不能连续两天及以上做同样的事。问最大的欢乐值是多少?

n105;ai,bi,ci104

换句话说就是每天做的事情都不一样。用 fi,j 表示第 i 天做 j 事件所得到的最大快乐值,枚举今天和明天做的事件,即:

fi+1,j=max{fi+1,j,fi,k+{a,b,c}k},jk

当然空间可以优化掉一维。

展开代码
#include <bits/stdc++.h>

using ll = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    
    int n;
    std::cin >> n;
    
    std::array<int, 3> f{};
    
    for (int i = 0; i < n; i++) {
        std::array<int, 3> c{};
        for (int &i : c) std::cin >> i;
        std::array<int, 3> nf{};
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) if (j != k) {
                nf[j] = std::max(nf[j], f[k] + c[j]);
            }
        }
        f = nf;
    }
    
    std::cout << *std::max_element(f.begin(), f.end()) << '\n';
    
    return 0;
}

Knapsack 1#

01 背包。

n100,w105,vi109

展开代码
#include <bits/stdc++.h>

using ll = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    
    int n, w;
    std::cin >> n >> w;
     
    std::vector<ll> f(w + 1);
    for (int i = 0; i < n; i++) {
        int wi, ci;
        std::cin >> wi >> ci;
        for (int j = w; j >= wi; j--) {
            f[j] = std::max(f[j], f[j - wi] + ci);
        }
    }
    
    std::cout << f.back() << '\n';
    
    return 0;
}

Knapsack 2#

01 背包。

n100,w109,vi103

考虑 fi,j 为前 i 个物品,得到 j 价值的最小容量。

展开代码
#include <bits/stdc++.h>

using ll = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    
    int n, w;
    std::cin >> n >> w;
    
    const int N = n * 1000;

    std::vector<std::vector<int>> f(n + 1, std::vector<int>(N + 1, 0x3f3f3f3f));
    f[0][0] = 0;
    for (int i = 0; i < n; i++) {
        int wi, vi;
        std::cin >> wi >> vi;
        for (int j = 0; j <= N; j++) {
            f[i + 1][j] = std::min(f[i + 1][j], f[i][j]);
            if (j + vi <= N) {
                f[i + 1][j + vi] = std::min(f[i + 1][j + vi], f[i][j] + wi);
            }
        }
    }
    
    for (int i = N; ~i; i--) {
        if (f[n][i] <= w) {
            std::cout << i << '\n';
            std::exit(0);
        }
    }
    
    return 0;
}

作者:patricky

出处:https://www.cnblogs.com/patricky/p/train-20230417.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   PatrickyTau  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu