AtCoder Educational DP Contest

news2024/11/26 0:52:01

A - Frog 1

大意

n块石头,第i块石头的高度为h_i。从石头i跳到石头j的花费是|h_i-h_j|

一只青蛙在石头1上,每次可以跳1步或2步,请问跳到石头n的最小代价是多少?

2 \le n \le 10^5, 1 \le h_i \le 10^4

思路

\operatorname{cost}(i,j)=|h_i-h_j|dp_i为青蛙跳到第i号石头时的最小代价。

每一个点都可以由前两个点转移而来,因此状态转移方程为:

dp_i=\min(dp_{i-1}+\operatorname{cost}(i-1,i), dp_{i-2}+\operatorname{cost}(i-2, i))

边界可由定义得出:dp_1=0,dp_2=\operatorname{cost}(1,2)

时间复杂度O(n)

代码

#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n;
    cin >> n;

    vector<int> a(n + 1), dp(n + 1, 0);
    for(int i = 1; i <= n; i++) cin >> a[i];

    auto cost = [&](int i, int j) -> int{
        int ret = a[i] - a[j];
        if(ret < 0) ret = -ret;
        return ret;
    };

    dp[2] = cost(1, 2);
    for(int i = 3; i <= n; i++)
        dp[i] = min(dp[i - 1] + cost(i, i - 1), dp[i - 2] + cost(i, i - 2));
    cout << dp[n] << endl;
    return 0;
}

B - Frog 2

大意

n块石头,第i块石头的高度为h_i。从石头i跳到石头j的花费是|h_i-h_j|

一只青蛙在石头1上,每次可以跳1~k步,请问跳到石头n的最小代价是多少?

2 \le n \le 10^5, 1 \le k \le 100, 1 \le h_i \le 10^4

思路

和上一题一样,设\operatorname{cost}(i,j)=|h_i-h_j|dp_i为青蛙跳到第i号石头时的最小代价。

每一个点都可以由前k个点转移而来(除了i < k的情况),因此状态转移方程为:

dp_i=\min(dp_{i-1}+\operatorname{cost}(i-1,i), dp_{i-2}+\operatorname{cost}(i-2, i), \cdots, dp_{\max(1, i - k)} + \operatorname{cost}(\max(1, i - k), i))

边界为dp_1=0

时间复杂度O(nk)

代码

#include <iostream>
#include <vector>
using namespace std;
#define int long long
const int INF = 0x3f3f3f3f;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int n, k;
    cin >> n >> k;
    vector<int> a(n + 1), dp(n + 1, INF);
    for(int i = 1; i <= n; i++) cin >> a[i];

    auto cost = [&](int i, int j){
        int ret = a[i] - a[j];
        return (ret > 0? ret: -ret);
    };

    dp[1] = 0;
    for(int i = 2; i <= n; i++){
        for(int j = max(1ll, i - k); j < i; j++) dp[i] = min(dp[i], dp[j] + cost(i, j));
    }
    cout << dp[n] << endl;
}

C - Vacation

大意

n天时间和3种活动。每天只能进行一个活动,且相邻两天不能做相同的活动。

i天做三种活动分别可以获得a_i,b_i,c_i点快乐值,求这n天里最大可以获得多少点快乐值。

1 \le n \le 10^5, 1 \le a_i,b_i,c_i \le 10^4

思路

dp_{i,j}为考虑到第i天,且第i天进行活动j的最大值。

由于相邻两天不能做相同的活动,所以dp_{i,j}只能从另外两个状态中的最大值转移过来。、

因此,状态转移方程为:

\begin{cases} dp_{i,1}=\max(dp_{i-1,2}, dp_{i-1,3}) + a_i \\ dp_{i,2}=\max(dp_{i-1,1}, dp_{i-1,3}) + b_i \\ dp_{i,3}=\max(dp_{i-1,1}, dp_{i-1,2}) + c_i \end{cases}

边界为dp_{0,1}=dp_{0,2}=dp_{0,3}=0,答案为\max(dp_{n,1}, dp_{n,2}, dp_{n,3})

时间复杂度O(n)

代码

#include <iostream>
#include <vector>
using namespace std;
#define int long long

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    int n;
    cin >> n;

    vector<int> a(n + 1), b(n + 1), c(n + 1);
    vector<int> dp1(n + 1, 0), dp2(n + 1, 0), dp3(n + 1, 0);
    for(int i = 1; i <= n; i++) cin >> a[i] >> b[i] >> c[i];

    for(int i = 1; i <= n; i++){
        dp1[i] = max(dp2[i - 1], dp3[i - 1]) + a[i];
        dp2[i] = max(dp1[i - 1], dp3[i - 1]) + b[i];
        dp3[i] = max(dp1[i - 1], dp2[i - 1]) + c[i];
    }
    cout << max(dp1[n], max(dp2[n], dp3[n])) << endl;
}

D - Knapsack 1

大意

n件物品和一个承重量为m千克的袋子。

i件物品的重量为w_i千克,价值为v_i元。

现在要挑选一些物品装入袋子里,求选择的物品的最大总价值。

1 \le n\le 100, 1 \le m \le 10^5, 1 \le w_i \le m, 1 \le v_i \le 10^9

思路

经典01背包问题,按照01背包的解法做即可。

注意需要long long。

时间复杂度O(nm)

代码

#include <iostream>
#include <vector>
using namespace std;
#define int long long

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int n, m;
    cin >> n >> m;

    vector<int> w(n + 1), v(n + 1), dp(m + 1, 0);
    for(int i = 1; i <= n; i++) cin >> w[i] >> v[i];

    for(int i = 1; i <= n; i++)
        for(int j = m; j >= w[i]; j--)
            dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
    
    cout << dp[m] << endl;
    return 0;
}

E - Knapsack 2

大意

n件物品和一个承重量为m千克的袋子。

i件物品的重量为w_i千克,价值为v_i元。

现在要挑选一些物品装入袋子里,求选择的物品的最大总价值。

1 \le n\le 100, 1 \le m \le 10^9, 1 \le w_i \le m, 1 \le v_i \le 10^3

思路

w_i很大,直接套用01背包计算,时间和空间肯定一定炸。

由于v_i很小,我们可以转换思路,设dp_{j}为价值为j 的最小重量,这样就不会炸了。

最后从大到小遍历j,找到符合dp_j \le m的直接输出j

时间复杂度O(ns),其中sj的取值范围,s=\sum v_i

代码

#include <iostream>
#include <vector>
using namespace std;
#define int long long
const int INF = 0x3f3f3f3f;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    int n, m;
    cin >> n >> m;

    vector<int> w(n + 1), v(n + 1);
    int sum = 0;
    for(int i = 1; i <= n; i++){
        cin >> w[i] >> v[i];
        sum += v[i];
    }

    vector<int> dp(sum + 1, INF);
    dp[0] = 0;
    
    for(int i = 1; i <= n; i++)
        for(int j = sum; j >= v[i]; j--)
            dp[j] = min(dp[j], dp[j - v[i]] + w[i]);
    
    for(int j = sum; j >= 0; j--)
        if(dp[j] <= m){
            cout << j << endl;
            break;
        }
    return 0;
}

F - LCS

题意

给定两个字符串,输出它们的任意一个最长公共子序列。

思路

求LCS时将最优策略保存下来,用x_{i,j}来表示状态(i,j)是否和(i-1,j)有关,y_{i,j}来表示状态(i,j)是否和(i,j-1)有关。

根据xy,就可以递归输出方案。

代码

#include <iostream>
#include <vector>
using namespace std;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    string x, y;
    cin >> x >> y;
    int n = x.size(), m = y.size();

    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    vector<vector<int>> f1(n + 1, vector<int>(m + 1));
    vector<vector<int>> f2(n + 1, vector<int>(m + 1));

    auto lcs = [&](string a, string b, int n, int m) -> void{
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++){
                if(a[i - 1] == b[j - 1]){
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    f1[i][j] = 1;
                    f2[i][j] = 1;
                }else if(dp[i - 1][j] > dp[i][j - 1]){
                    dp[i][j] = dp[i - 1][j];
                    f1[i][j] = 1;
                }else{
                    dp[i][j] = dp[i][j - 1];
                    f2[i][j] = 1;
                }
            }
    };

    string ans = "";
    auto dfs = [&](auto self, string a, string b, int i, int j) -> void{
        if(i == 0 || j == 0) return;
        self(self, a, b, i - f1[i][j], j - f2[i][j]);
        if(a[i - 1] == b[j - 1]) ans.push_back(a[i - 1]);
    };

    lcs(x, y, n, m);
    dfs(dfs, x, y, n, m);
    cout << ans << endl;
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1600223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态规划Dynamic programming详解-编辑距离问题【python】

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

【笔试训练】day3

今天的题又简单了很多欸 1.简写单词 没思路 代码&#xff1a; #include <iostream> #include<string> using namespace std;int main() {string str;string ans;getline(cin,str);if(str[0]>Z)ans(str[0]-32);else ansstr[0];for(int i1;i<str.size();i…

Linux第88步_非阻塞IO实验

非阻塞IO是“应用程序”对“驱动设备”进行操作&#xff0c;若不能获取到设备资源&#xff0c;则非阻塞IO应用程序的线程不会被“挂起”&#xff0c;即线程不进入休眠&#xff0c;而是一直“轮询”&#xff0c;直到获取到设备资源为止&#xff0c;或者直接放弃。 非阻塞IO应用举…

mybatis(9)-逆向工程+PageHelper+注解方式开发

最后一篇&#xff01;&#xff01; 1、逆向工程1.1、普通版1.2、增强版 2、PageHelper2.1 limit2.2 插件 3、注解开发3.1 Insert3.2Delete3.3 Update3.4 Select Results 1、逆向工程 1.1、普通版 所谓的逆向工程是&#xff1a;根据数据库表逆向生成Java的pojo类&#xff0c;S…

纯golang开发的mqtt server

Mochi-MQTT Server github地址&#xff1a;https://github.com/mochi-mqtt/server Mochi-MQTT 是一个完全兼容的、可嵌入的高性能 Go MQTT v5&#xff08;以及 v3.1.1&#xff09;中间件/服务器。 Mochi MQTT 是一个完全兼容 MQTT v5 的可嵌入的中间件/服务器&#xff0c;完…

YoloV9实战:从Labelme到训练、验证、测试、模块解析

模型实战 训练COCO数据集 本次使用2017版本的COCO数据集作为例子&#xff0c;演示如何使用YoloV8训练和预测。 下载数据集 Images: 2017 Train images [118K/18GB] &#xff1a;http://images.cocodataset.org/zips/train2017.zip2017 Val images [5K/1GB]&#xff1a;htt…

选择最佳 PoE 布线系统的 3 个步骤

选择合适的 POE 布线系统的重要性 在不断发展的信息和通信技术 &#xff08;ICT&#xff09; 领域&#xff0c;以太网供电 &#xff08;PoE&#xff09; 布线系统已成为一种革命性的解决方案&#xff0c;它简化了网络设备的部署和管理&#xff0c;同时优化了电力传输。从智能建…

傅里叶变换到底是什么

傅里叶变换到底是什么 有一个f&#xff08;t&#xff09;经傅里叶变换公式转化成F&#xff08;w&#xff09;&#xff1b; F&#xff08;w&#xff09;包括 欧拉公式转化成无限包括sin cos的函数相加。sin cos前面的参数a不为0说明这个周期函数分量存在&#xff0c;是某一种有…

基本模拟概念

目标&#xff1a; 讨论模拟电子技术的基本特性 描述模拟信号 分析信号源 解释放大器的特性 1.1模拟电子学 电子学可以划分成很多的分类来研究。其中最基本的一种分类方式是将信号分成可由 二进制数字表示的数字信号和由连续变化量表示的模拟信号。数字电子学包括所有的算术 和…

想做好抖音直播运营,这81个专业术语你必须得知道 沈阳新媒体运营培训

1.起号 释义&#xff1a;从0基础创建账号到1账号已具备基础模型&#xff0c;启动一个直播间&#xff0c;并使其能稳定卖出去东西的过程。简单一点来说&#xff0c;就是冷启动&#xff0c;通过活动或者其他方式获得快速大量曝光的一种形式。目前主流起号方式为&#xff1a;▼活…

【C++】unordered_set和unordered_map

底层哈希结构 namespace hash_bucket {template<class T>struct HashData{T _data;struct HashData* next nullptr;HashData(const T& data):_data(data){}};//仿函数:这里直接用开散列仿函数template <class K>struct HashFunc{size_t operator()(const K&a…

attention and tell论文【无标题】

这个公式使用LaTeX语法表示为&#xff1a; ( i t f t o t c t ) ( σ σ σ tanh ⁡ ) T D m n , n ( E y t − 1 h t − 1 x t ) \begin{pmatrix}i_t \\f_t \\o_t \\c_t\end{pmatrix} \begin{pmatrix}\sigma \\\sigma \\\sigma \\\tanh\end{pmatrix}T_{Dmn,n}\begin{pmatri…

HackMyVM-Gift

目录 信息收集 arp nmap WEB dirsearch hydra ssh连接 get root 信息收集 arp ┌─[rootparrot]─[~] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.102 Starting arp-scan 1.10.0 with 256 hosts (https://git…

动态规划算法求解最长公共子序列

动态规划算法是运筹学中求解多阶段决策问题的经典算法&#xff0c;本文将介绍动态规划算法的基本思想&#xff0c;并介绍如何使用动态规划算法求解最长公共子序列问题。 1. 动态规划算法的基本思想 动态规划算法本质也是基于分治思想&#xff0c;将待求解问题分解成若干个子问…

「GO基础」目录

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

02_JavaWeb中的Tomcat(详解)

文章目录 Tomcat1, 概述1.1 安装1.2 目录结构1.3 启动/停止 2, 资源部署2.1 直接部署: 主要和重要的方式2.2 虚拟映射: 重要2.2.1 方式一:2.2.1 方式二: 2.3 原理解析 3, Tomcat组件3.1 Connector3.2 Engine3.2.1 Host3.2.1.1 Context 4, 其它: 重要4.1 设置 Tomcat 1, 概述 w…

(踩坑)Please refer to 异常和Error creating bean with name 异常

一、Please refer to 异常 如图所示&#xff0c;在使用maven构建项目的时候&#xff0c;如果提示该错误&#xff0c;则可能是xml配置文件有问题或者测试类等。但是没有明确的异常信息&#xff0c;所以做以下小改动&#xff0c;可以查看异常信息。 在IDEA工具中&#xff0c;打…

08 SQL进阶 -- 集合运算 -- 表的连结(JOIN)

1. 连结(JOIN) 前一节我们学习了 UNION和INTERSECT 等集合运算, 这些集合运算的特征就是以行方向为单位进行操作. 通俗地说, 就是进行这些集合运算时, 会导致记录行数的增减。使用 UNION 会增加记录行数,而使用 INTERSECT 或者 EXCEPT 会减少记录行数。 但这些运算不能改变…

【Java开发指南 | 第十篇】Java修饰符

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 JAVA修饰符访问修饰符非访问修饰符static 修饰符final 修饰符abstract 修饰符synchronized 修饰符transient 修饰符volatile 修饰符 JAVA修饰符 修饰符用来定义类、方法或者变量&#xff0c;通常放在语句的最前…

2024年【高处安装、维护、拆除】考试题库及高处安装、维护、拆除复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高处安装、维护、拆除考试题库是安全生产模拟考试一点通生成的&#xff0c;高处安装、维护、拆除证模拟考试题库是根据高处安装、维护、拆除最新版教材汇编出高处安装、维护、拆除仿真模拟考试。2024年【高处安装、维…