DP(1500-1700)(刷题)

news2024/9/23 13:29:59

1.状态机模型:https://codeforces.com/contest/1984/problem/C2

记一下max与min状态转移即可,下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
ll a[200010],t,n;
ll dp[200010][2];//dp[i][0]表示min,dp[i][1]表示max 
ll cnt[200010][2];//cnt[i][0]表示取到dp[i][0]的方法数,cnt[i][1]表示取到dp[i][1]的方法数 
ll mod=998244353;
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        dp[1][0]=a[1];
        if(a[1]>=0) cnt[1][0]=2;
		else cnt[1][0]=1; 
		if(a[1]>=0) cnt[1][1]=2;
		else cnt[1][1]=1; 
		dp[1][1]=abs(a[1]);
		for(int i=2;i<=n;i++)
		{
			dp[i][0]=(dp[i-1][0]+a[i]);
            if(dp[i][0]>=0) cnt[i][0]=cnt[i-1][0]*2%mod;
			else cnt[i][0]=cnt[i-1][0];
			dp[i][1]=max(abs(dp[i-1][0]+a[i]),dp[i-1][1]+a[i]);
			if(dp[i][1]==dp[i-1][1]+a[i]&&dp[i][1]==abs(dp[i-1][0]+a[i]))
			{
				if(dp[i-1][1]!=dp[i-1][0])
				{
				cnt[i][1]=2*cnt[i-1][1]%mod;
				if(dp[i-1][0]+a[i]>=0) cnt[i][1]=(cnt[i][1]+2*cnt[i-1][0]%mod)%mod;
				else cnt[i][1]=(cnt[i][1]+cnt[i-1][0])%mod;
			    }
				else{
					cnt[i][1]=2*cnt[i-1][1]%mod;
				}
			}
			else if(dp[i][1]==dp[i-1][1]+a[i])
			{
				cnt[i][1]=2*cnt[i-1][1]%mod;
			}
			else{
				if(dp[i-1][0]+a[i]>=0) cnt[i][1]=2*cnt[i-1][0]%mod;
				else cnt[i][1]=cnt[i-1][0];
			}
		}
		cout<<cnt[n][1]<<endl;
	}
}

2.DFS:https://codeforces.com/contest/1975/problem/D

首先先让红蓝相遇,然后再遍历一遍树,下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> edge[200010];
int t,n,a,b,x,y;
int cnt;
int track[200010];
int h[200010];
int dis;
void dfs(int x,int cnt1,int fa)//两点相差的距离 
{
	if(a==x){
		cnt=cnt1;
		track[a]=fa;
		return;
	}
	for(int i=0;i<edge[x].size();i++)
	{
		int son=edge[x][i];
		if(son==fa) continue;
		track[son]=x;
		dfs(son,cnt1+1,x);
	}
}
void dfs1(int x,int fa)//建树高度 
{
	h[x]=0;
	for(int i=0;i<edge[x].size();i++)
	{
		int son=edge[x][i];
		if(son==fa) continue;
		dfs1(son,x);
		h[x]=max(h[x],h[son]+1);
	}
}
int dfs3(int x,int fa){
	int res=0;
	for(int i=0;i<edge[x].size();i++){
		int son=edge[x][i];
		if(son==fa) continue;
		res+=2+dfs3(son,x);
	}
	return res; 
} 
int dfs2(int x,int fa){
	int k=-1;//记录最长链
	int lon=-1;
	for(int i=0;i<edge[x].size();i++){
		int son=edge[x][i];
		if(son==fa) continue;
		if(h[son]>lon){
			lon=h[son];
			k=i;
		}
	}
	int res=0;
	for(int i=0;i<edge[x].size();i++){
		int son=edge[x][i];
		if(son==fa) continue;
		if(i==k) res+=1+dfs2(son,x);
		else res+=dfs3(son,x)+2;
	}
	return res; 
}
int find(int start,int dis){
	if(dis==0) return start;
	return find(track[start],dis-1); 
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n;
		cin>>a>>b;
		dis=0;
		vector<int>::iterator it;
		memset(edge,0,sizeof(edge));
		for(int i=1;i<=n-1;i++)
		{
			cin>>x>>y;
			edge[x].push_back(y);
			edge[y].push_back(x);
		}
		//找出蓝点到红点的距离
		cnt=0;
		dfs(b,0,-1); 
		dis=cnt/2;
		int ck=find(a,dis);
		dfs1(ck,-1);
		if(cnt%2==0) dis+=dfs2(ck,-1);
		else dis+=1+dfs2(ck,-1); 
		cout<<dis<<endl;
	}
}

3.区间DP:https://codeforces.com/contest/1969/problem/C

我们令dp[i][j]表示前i个用<=j次的min,对于状态的更新,我们考虑dp[i][k]的第i个元素,我们发现假如没有次数限制对于长度n我们用最坏用n-1可以更新到min,回过头来,假如进行t次操作,一定可以让最后长度t+1的一段变成这个区间中最小的值,于是我们枚举t,它可以让最后t+1个变成其中的min,具体地,我们不妨令k=2(k>=3同理),那么所有的答案可能的情况就是倒数3个变成其中min,倒数2个变成其中min以及最后一个没有变的3种情况,消耗的次数分别为2,1,0(最优答案一定是其中一个)

或者说,我们从集合的角度分析,所有涉及到a[i]的可能(没涉及的就是dp[i-1][j]+a[i]):

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll t,n,k;
ll a[300010][13];
ll b[300010];
ll dp[300010][11];
int main()
{
	cin>>t;
	while(t--){
		cin>>n>>k;
		for(ll i=1;i<=n;i++) cin>>b[i];
		//搜索每一个点的前k+1个内的min
		for(ll i=1;i<=n;i++){
			ll ans=b[i];
			for(ll j=1;j<=k+1;j++){
				ans=min(ans,b[max((ll)1,i-j+1)]);
				a[i][j]=ans;
			}
		}
		/*for(int i=1;i<=n;i++){
			cout<<endl;
			for(int j=1;j<=k+1;j++) cout<<a[i][j]<<" ";
		}
		*/
		//开始DP
		
		for(ll i=0;i<=k;i++) dp[1][i]=b[1];
		for(ll i=2;i<=n;i++){
			for(ll j=0;j<=k;j++){
				dp[i][j]=dp[i-1][j]+b[i];
				for(ll w=1;w<=j;w++){
					if(i-(w+1)<0){
						dp[i][j]=min(dp[i][j],a[i][k+1]*i);
					}
					else dp[i][j]=min(dp[i][j],dp[i-w-1][j-w]+a[i][w+1]*(w+1));
				}
			}
		}
		
		cout<<dp[n][k]<<endl; 
	}
}

4.模拟(类似DP转移的思想):https://codeforces.com/contest/1976/problem/C

我们先枚举第n+m+1走的答案,然后对于前面的一个人退出,看看有没有想选这个但是被迫走的,有的化取最近的更新,下面的一个空位由n+m+1填,反之若没有就只好让n+m+1来填,同时从后往前依次更新被迫的人的位置。下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll t,a[300010],b[300010],n,m;
bool wh[300010];
ll cnt1,cnt2;
int main()
{
	cin>>t;
	while(t--)
	{
		ll ans[200020]={0};
		cin>>n>>m;
		for(ll i=1;i<=n+m+1;i++) cin>>a[i];
		for(ll i=1;i<=1+n+m;i++) cin>>b[i];
		//计算dp[n+m+1]
		ll cnt1=0,cnt2=0;
		ll res=0;
		for(ll i=1;i<=n+m;i++)
		{
			if(a[i]>b[i]&&cnt1<n){
				cnt1++;
				wh[i]=0;
				res+=a[i];
			}
			else if(a[i]>b[i])
			{
				cnt2++;
				wh[i]=1;
				res+=b[i];
			}
			else if(a[i]<b[i]&&cnt2<m){
				cnt2++;
				wh[i]=1;
				res+=b[i];
			}
			else{
				cnt1++;
				wh[i]=0;
				res+=a[i];
			}
		}
		ans[n+m+1]=res;
		//转移
		ll ca=n+m+1,cb=n+m+1;//ca:最先被迫编程的 
		for(ll i=n+m;i>=1;i--){
			ll hh=res;
			if(cb==n+m+1&&wh[i]==0) hh+=a[n+m+1]-a[i];
			else if(ca==n+m+1&&wh[i]) hh+=b[ca]-b[i];
			else if(wh[i]) hh+=abs(a[ca]-b[ca])-b[i]+a[n+m+1];
			else  hh+=abs(a[cb]-b[cb])-a[i]+b[n+m+1];
			if(wh[i]&&a[i]>b[i]) cb=i;
			if(!wh[i]&&a[i]<b[i]) ca=i;
			ans[i]=hh;
		}
		
		for(ll i=1;i<=n+m+1;i++) cout<<ans[i]<<" ";
		cout<<endl;
	}
}

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

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

相关文章

啊?现在不懂 AI ,相当于十年前不懂电脑?

最近有关萝卜快跑的新闻铺天盖地&#xff0c;一篇篇都在唱衰&#xff0c;好像千万滴滴师傅立马就要失业了一样。 还没等多久&#xff0c;在朋友圈看到这样一句话&#xff0c;“现在不懂 AI &#xff0c;相当于十年前不懂电脑”。 我想了许久&#xff0c;最终不得不承认这个事实…

深度学习入门——误差反向传播

要正确理解误差反向传播法&#xff0c;我个人认为有两种方法&#xff1a;一种是基于数学式&#xff1b;另一种是基于计算图&#xff08;computational graph&#xff09; 前者是比较常见的方法&#xff0c;机器学习相关的图书中多数都是以数学式为中心展开论述的。因为这种方法…

达梦数据库的系统视图v$sqltext

达梦数据库的系统视图v$sqltext 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$SQLTEXT 是一个系统视图&#xff0c;用于显示当前正在执行或最近执行的SQL语句的文本信息。这个视图对于监控和分析数据库中的SQL活动非常有用&#xff0c;尤其是在需要调试性…

【python】OpenCV—Coordinates Sorted Clockwise

文章目录 1、需求介绍2、算法实现3、完整代码 1、需求介绍 调用 opencv 库&#xff0c;绘制轮廓的矩形边框&#xff0c;坐标顺序为右下→左下→左上→右上&#xff0c;我们实现一下转化为熟悉的 左上→右上→右下→左下 形式 按照这样的顺序组织边界框坐标是执行透视转换或匹…

13. C++继承 | 详解 | 虚拟继承及底层实现

目录 1.定义 1.1继承的概念 1.2 继承的定义 2. 对象赋值转换 3. 继承中的作用域 a. 隐藏/重定义 (Hiding/Redefinition) b. 重载 (Overloading) c. 重写/覆盖 (Overriding) d. 编译报错 (Compilation Error) 4. 派生类的默认成员函数 构造 拷贝构造 运算符重载 析…

处理uniapp刷新后,点击返回按钮跳转到登录页的问题

在使用uniapp的原生返回的按钮时&#xff0c;如果没有刷新会正常返回到对应的页面&#xff0c;如果刷新后会在当前页反复横跳&#xff0c;或者跳转到登录页。那个时候我第一个想法时&#xff1a;使用浏览器的history.back()方法。因为浏览器刷新后还是可以通过右上角的返回按钮…

Vscode+Pyside6开发之虚拟环境配置以及错误解决

Pyside开发之虚拟环境配置以及错误解决 开发环境一、项目创建以及虚拟环境设置1.创建项目2. 新建py文件,新建虚拟环境3.激活虚拟环境二、项目位置改变pip命令报错1.删除原来的虚拟环境2. 产生包列表文件requirements.txt3.重新创建虚拟环境4.重新安装包文件5.其他错误开发环境…

操作系统 输入输出系统

输入输出系统 I/O系统的功能、模型和接口 功能 隐藏物理设备的细节&#xff1a;仅向上层进程提供少量的、抽象的读/写命令 与设备无关性&#xff1a;用户不仅可以使用抽象的I/O命令&#xff0c;还可使用抽象的逻辑设备名来使用设备 提高处理机和I/O设备的利用率&#xff1a;…

IDEA SpringBoot实现定时任务(保姆级教程,超详细!!!)

目录 1. 前言 2. 创建SpringBoot项目 3. Maven依赖引入 4. 创建定时任务 5. 问题&#xff1a;执行时间延迟和单线程执行 5.1 问题原因 5.2 解决方式 1. 前言 在现代化应用中&#xff0c;定时任务&#xff08;Scheduled Tasks&#xff09;是不可或缺的一部分&#xff…

pytorch学习(五)tensorboard使用

1. 创建环境 首先创建一个环境: conda create -n pytorch conda activate pytorch 然后安装tensorboard pip install tensorboard 安装opencv pip install opencv-python 2. 简单的案例 标量和图像的显示&#xff1a; 2.1标量实现的方法是add_scalar,第一个参数是给显…

Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图

今天和大家分享一个基于Pony模型训练的二次元模型&#xff1a;二次元插图。关于该模型有4个不同的分支版本。 1.5版本&#xff1a;loar模型&#xff0c;推荐底模型niji-动漫二次元4.5。 xl版本&#xff1a;SDXL模型版本 mix版本&#xff1a;光影减弱&#xff0c;减少SDXL版本…

21天学通C++:第十三、十四章节

第十三章&#xff1a;类型转换运算符 类型转换是一种机制&#xff0c;让程序员能够暂时或永久性改变编译器对对象的解释。注意&#xff0c;这并不意味着程序员改变了对象本身&#xff0c;而只是改变了对对象的解释。可改变对象解释方式的运算符称为类型转换运算符。 为何需要…

数据库端口LookUp功能:从数据库中获取并添加数据到XML

本文将为大家介绍如何使用知行之桥EDI系统数据库端口的Lookup功能&#xff0c;从数据库中获取数据&#xff0c;并添加进输入的XML中。 使用场景&#xff1a;期待以输入xml中的值为判断条件从数据库中获取数据&#xff0c;并添加进输入xml中。 例如&#xff1a;接收到包含采购…

Linux 06-01:简易shell编写

考虑一下这个与shell典型的互动&#xff1a;ls、ps 用下图的时间轴来表示事件的发生次序。其中时间从左向右。shell由标识为sh的方块代表&#xff0c;它随着时间的流逝从左向右移动。shell从用户读入字符串"ls"。shell建立一个新的进程&#xff0c;然后在那个进程中运…

Three.js 实战【2】—— 船模型海上场景渲染

停止了好久没有更新three这方面的文章了&#xff0c;从上两年还是vue2&#xff0c;一下子都换到vue3了&#xff0c;下面这些three都是基于vue3来进行开发的哈&#xff0c;先看一下这篇文章实现的效果哈。其中关于模型什么的资源都放在Git上了 初始化场景 安装three就直接通过n…

Java——集合(Queue)

1.Queue 接口的常用功能 除了基本的 Collection 操作外&#xff0c;队列还提供其他的插入、提取和检查操作。每个方法都存在 两种形式&#xff1a;一种抛出异常&#xff08;操作失败时&#xff09;&#xff0c;另一种返回一个特殊值&#xff08; null 或 false &#xff…

RPA鼠标按键使用技巧

RPA鼠标按键使用技巧 Mouse.MouseAuto.Action命令出错&#xff0c;调用的目标发生了异常&#xff0c;Exception in Mouse.Action元素不可用怎么解决 出现问题 1.想要实现的效果鼠标移动到录屏工具的小球上2.点击开始按钮开始录屏现象&#xff0c;鼠标没有移动痕迹&#xff0c…

爬虫案例(读书网)(下)

上篇链接&#xff1a; CSDN-读书网https://mp.csdn.net/mp_blog/creation/editor/139306808 可以看见基本的全部信息&#xff1a;如(author、bookname、link.....) 写下代码如下&#xff1a; import requests from bs4 import BeautifulSoup from lxml import etreeheaders{…

SSD实现

一、模型 此模型主要由基础网络组成&#xff0c;其后是几个多尺度特征块。基本网络用于从输入图像中提取特征&#xff0c;因此它可以使用深度卷积神经网络。 单发多框检测选用了在分类层之前截断的VGG&#xff0c;现在也常用ResNet替代&#xff1b;可以设计基础网络&#xff0c…

【LeetCode】162. 寻找峰值

1. 题目 2. 分析 这道题的难点有二&#xff1a;第一&#xff0c;知道用二分法求解&#xff1b;第二&#xff0c;二分判断的标准是什么&#xff1f;传统的题目的二分标注都是跟某个固定的值做比较&#xff0c;但是此题不然。此题的比较对象是相邻的元素。 不要硬凭自己的脑子…