算法训练1

news2025/1/13 10:17:14

01背包问题

背包状态方程----动态规划

二维dp

使用 f[i][j] = max(f[i-1][j] ,f[i-1][j - w[i]] + v[i]);

 伪代码:

int dp[100][100];
void test6() {
	int n;  //装备数量
	int m;  //背包容量

	int v[105], w[105]; //前面空间,后面价值
	for (int i = 1; i <= n; i++) {
		for (int j = m; j >= 0; j--) {
			if (j >= v[i]) {
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
			}
			else {
				dp[i][j] = dp[i - 1][j];
			}
		}
	}
}

 其中,dp中的横坐标i代表的是第i个装备,纵坐标 j 为背包容量,由于这里dp一直记录的是最大的,所以可以优化为一维dp

 同理的一道题:

 使用一维dp,注意的是:进行更新 f[ ]时,要从后面开始更新,这样可以使用的f[j - v[i]] 全是上次草药的值,如果从小往大进行更新,会导致后面更新,装两次一样的草药。导致错误。

void test3() {
	int timeAll, num;
	scanf("%d%d", &timeAll, &num);
	int v[105],w[105];
	int f[1005];
	for (int i = 1; i <= num; i++) {
		scanf("%d %d", &v[i], &w[i]);
	}
	for (int i = 0; i <= timeAll; i++) {
		f[i] = 0;
	}
	for (int i = 1; i <= num; i++) {
		for (int j = timeAll; j >= 0; j--) {
			if (j >= v[i]) {
				f[j] = max(f[j], f[j - v[i]] + w[i]);
			}
			else {
				f[j] = f[j];
			}
		}
	}


	printf("%d", f[timeAll]);
}

桶排序+暴力处理

 这里就不断处理最大值,最大湿度衣服进行烘干,然后暴力执行。

//堆排序
int f[500005];
void test5() {
	int n, a, b;
	scanf("%d%d%d", &n, &a, &b);
	int max = 0, sum = 0,time = 0;
	for (int i = 1; i <= n; i++) {
		int k;
		scanf("%d", &k);
		f[k]++;
		if (k > max) {
			max = k;
		}
	}

	while (1) {
		if (max <= sum) {
			break;
		}
		f[max]--;
		if (max > b) {
			f[max - b] += 1;
		}
		while(f[max] == 0) {
			max--;
		}

		sum += a;
		time += 1;
	}
	printf("%d", time);

}

二分答案:

题解 P2678 【跳石头】 - 洛谷专栏 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/article/08mxthsv

运用二分答案,进行枚举判断答案是否正确

比如:

 使用check函数检查答案是否正确,运用二分答案:两个要素

单调性,有界性。答案可以枚举出来

#define _CRT_SECURE_NO_WARNINGS 
#include<cstdio> 
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;
int H[1000005];
int N, M;
bool check2(int l) {
	int count = 0;
	for (int i = 1; i <= N; i++) {
		if (H[i] > l) {
			count += H[i] - l;
			if (count >= M) {
				return true;
			}
		}
	}
	return false;
}

int max(int a, int b) {
	return a > b ? a : b;
}

void test8() {

	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N; i++) {
		scanf("%d", &H[i]);
	}
	sort(H + 1, H + 1 + N);

	int left = 1, right = H[N], ans = 0;
	while (left <= right) {
		int mid = (left + right) / 2;
		if (check2(mid)) {
			ans = max(ans, mid);
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}
	cout << ans;

}
int main() {
	test8();
}

 还有这题:P1824 进击的奶牛 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 同理:使用二分答案,解决


 

#define _CRT_SECURE_NO_WARNINGS 
#include<cstdio> 
#include<cstring>
#include<iostream>
#include<algorithm>
int V[200005];
int N, C, H;
using namespace std;
int check(int k) {
	int last = V[1], count = 0;
	for (int i = 2; i <= N; i++) {
		if (V[i] - last < k) {
			count++;
			if (H < count)return 1;
		}
		else {
			last = V[i];
		}

	}
	return 0;
}

int max(int a, int b) {
	return a > b ? a : b;
}

void swap(int* a, int* b) {
	int t = *a;
	*a = *b;
	*b = t;
}

void test7() {

	scanf("%d %d", &N, &C);
	for (int i = 1; i <= N; i++) {
		scanf("%d", &V[i]);
	}
	H = N - C;

	sort(V+1,V+N+1);
	

	int left = 1, right = V[N], ans = 0;
	while (left <= right) {
		int mid = (left + right) / 2;
		if (check(mid) == 0) {
			ans = max(mid, ans);
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}
	printf("%d", ans);

}
int main() {
	test7();
}

并查集

比如:

P3367 【模板】并查集 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

找祖先,就一直找到最初的组件,判断是否相等,如果相等,就说明这两个是在同一个集合中。

int find(int x) {
	while (x != f[x]) {
		x = f[x];
	}
	return x;
}

//路径压缩,循环实现
int find(int x){
    while (x != f[x]){
        f[x] = f[f[x]];
         x = f[x]
    }
    return x;
}

//路径压缩,递归实现
int find(int x){
    if(x == f[x])
        return x;
    return f[x] = find[f[x]];
}

 路径压缩后会可以使查询祖先时,快不少。

并查集还有一个重要的出来查询之外,还有合并了

这里可以直接把一个元素的祖先赋值给一个元素的祖先

void merge(int a,int b){
    int a1 = find(a);
    int a2 = find(b);
    f[a1] = a2;
}

 

#define _CRT_SECURE_NO_WARNINGS 
#include<cstdio> 
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;
int N, M;
int f[10005];
void init() {
	for (int i = 1; i <= N; i++) {
		f[i] = i;
	}
}

int find(int x) {
	while (x != f[x]) {
		f[x] = f[f[x]];
		x = f[x];
	}
	return x;
}

void test8() {
	cin >> N >> M;
	init();
	for (int i = 1; i <= M; i++) {
		int z, x, y;
		cin >> z >> x >> y;
		if (z == 1) {
			f[find(x)] = find(y);
		}
		else if (z == 2) {
			if (find(x) == find(y)) {
				cout << "Y\n";
			}
			else {
				cout << "N\n";
			}
		}
	}
	
}
int main() {
	test8();
}

最小生成树

算法:prim,kruskal算法

主要学习了kruskal算法

运用到了并查集。P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

顺便学习了c++中sort函数,自定义排序方式,

图中的边权值,进行排序。

kruskal:先找出最小没有连接的边,然后判断如果连接后有没有回路,如果有回路,就舍弃这条边,没有就把这条边加入,然后再进行判断下一条边。

P1195 口袋的天空 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

类似的,这个是需要把n个点构造成k棵最小生成树,所以只要加入的边等于n-k就行了

附上代码

#define _CRT_SECURE_NO_WARNINGS 
#include<cstdio> 
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int N, M, K;
int f[1005];

struct edge {
	int v, u, w;
}edges[10005];

int find(int x) {
	while (f[x] != x) {
		f[x] = f[f[x]];
		x = f[x];
	}
	return x;
}
bool cmp(edge a, edge b) {
	return a.w < b.w;
}

void kruskal() {
	int ans = 0, cnt = 0;
	sort(edges + 1, edges + M + 1, cmp);
	for (int i = 1; i <= M; i++) {
		int a1 = find(edges[i].u);
		int a2 = find(edges[i].v);
		if (a1 == a2) {
			continue;
		}
		ans += edges[i].w;
		f[a1] = a2;    //连接两个顶点
		cnt++;
		if (cnt == N - K) {
			cout << ans;
			return;
		}

	}
	cout << "No Answer";
}

void test() {
	cin >> N >> M >> K;
	for (int i = 1; i <= N; i++) {
		f[i] = i;
	}
	for (int i = 1; i <= M; i++) {
		cin >> edges[i].u >> edges[i].v >> edges[i].w;
	}
	kruskal();
}
int main() {
	test();
}

 

最短路径

dijkstra算法+链式前向星存边,

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include <algorithm>
#include<cstring>
#define inf 2147483647
using namespace std;
long long dis[10005];
bool vis[10005];
int head[10005];
int n, m, s,cnt = 0;
//在这里head数组储存i点的一条边的编号,edge中的next表示的是起点相同的边的编号,
//可以从加边那里深刻理解
//链式前向星存边
struct edge {
	int next;
	int to;
	int val;
}edges[500005];

void dijkstra() {
	dis[s] = 0;
	int cur = s;
	while (!vis[cur]) {
		vis[cur] = true;
		for (int i = head[cur]; i != 0; i = edges[i].next) {
			if (!vis[edges[i].to] && dis[edges[i].to] > dis[cur] + edges[i].val) {
				dis[edges[i].to] = dis[cur] + edges[i].val;
			}
		}
		int min = inf;
		for (int i = 1; i <= n; i++) {
			if (!vis[i] && min > dis[i]) {
				min = dis[i];
				cur = i;
			}
		}
	}

	for (int i = 1; i <= n; i++) {
		cout << dis[i] <<" ";
	}
}

//加边
void add(int a,int b,int c) {
	edges[++cnt].next = head[a];
	edges[cnt].to = b;
	edges[cnt].val = c;
	head[a] = cnt;            //记录编号
}

void test() {
	cin >> n >> m >> s;

	for (int i = 1; i <= m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		add(a, b, c);
	}
	for (int i = 1; i <= n; i++) {
		dis[i] = inf;
	}
	dijkstra();
}


int main() {
	test();
}

训练总结:昨天晚上加今天一天完成了这所有的训练,确实收获不少。

靠思维,暴力解决:A,,K,L

动态规划还是不太熟练, B

二分答案,能够理解。  C,D,E,F

 并查集:G,H

最小生成树:H,I

最短路径:J

思路有个大概,但是完全自己想出来,还是有点难度

 

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

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

相关文章

快速排序(上)

快速排序 前言 快速排序算法是最流行的排序算法,且有充足的理由,因为在大多数情况下,快速排序都是最快的。所以学习快速排序算法十分有必要。当然&#xff0c;既然它这么好&#xff0c;也就不太容易理解。 正文 Hoare版快排 快速排序是Hoare在1962年提出的一种二叉树结构的…

专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用

知足知不足&#xff0c;有为有不为&#xff01;——《心安即是归处》 目录 专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用 专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用

SpringDataJPA(三):多表操作,复杂查询

一、Specifications动态查询 有时我们在查询某个实体的时候&#xff0c;给定的条件是不固定的&#xff0c;这时就需要动态构建相应的查询语句&#xff0c;在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。 import …

Spring Boot 整合 Dubbo3 + Nacos 2.4.0

准备工作&#xff1a;Nacos 一、前置工作 安装Nacos&#xff0c;参考&#xff1a;Nacos 快速开始 此次安装 Nacos 最新版本&#xff1a;2.4.0 单机版 安装教程&#xff1a;Linux 安装 nacos 2.4.0-CSDN博客 二、创建配置文件 创建命名空间 新增配置文件 dubbo:application:i…

关于uniapp的vue2.x版本的路由守卫拦截方案

使用uni-read-pages和uni-simple-router实现&#xff0c;方案思路如下 首先在packge.json把下面两个依赖npm install 一下&#xff0c;我目前是这两个版本&#xff0c;别的版本号没有测试过 "dependencies": {"uni-read-pages": "^1.0.5",&quo…

matplotLib在图中标出最后一个点的值

import matplotlib.pyplot as plt import numpy as np# 生成100个随机数据 data np.random.rand(100)# 绘制数据 plt.plot(data, labelData Points)# 获取最后一个数据点的位置和值 last_x len(data) - 1 last_y data[-1]# 用红圈标出最后一个点 plt.plot(last_x, last_y, r…

《动手做科研》09. 万事具备,只欠行动

地址链接:《动手做科研》09. 万事具备&#xff0c;只欠行动 欢迎加入我的知识星球&#xff0c;定期分享AI论文干货知识&#xff01; 导读: 当你坚持学习到这一步&#xff0c;并且之前的内容都有跟着操作&#xff0c;那么恭喜你&#xff0c;你已经在脑力层面消化了最难的知识&am…

AI表情神同步!LivePortrait安装配置,一键包,使用教程

快手在AI视频这领域还真有点东西&#xff0c;视频生成工具“可灵”让大家玩得不亦乐乎。 现在又开源了一款超好玩的表情同步&#xff08;表情控制&#xff09;项目。 一看这图片&#xff0c;就知道是小视频平台出的&#xff0c;充满了娱乐性。发布没几天就已经有8000Star。 项…

7月Langchain-Chatchat 0.3.1最新 win系统-安装教程,踩坑2小时,5分钟拿去!

Win11安装 langchain-chatchat 0.3.1最新版 1. 虚拟环境安装和python包安装 conda create -n chat310 python3.10#这里很重要 需要先安装cuda版本的torch pip install torch2.3.1 torchvision0.18.1 torchaudio2.3.1 --index-url https://download.pytorch.org/whl/cu121pip…

六种方法实现Python文件之间的互动!

一、exec() 首先&#xff0c;我们生成一个名为**“file1.py”的python文件**&#xff1a; # file1.py print("Hello from file1!")然后&#xff0c;再生成一个名为“main.py”的python文件&#xff1a; # main.py filename file1.py with open(filename) a…

vlunstack-1(横向,phpmyadmin拿shell,xycms拿shell,cs和msf联动)

Vulnstack-1 内网环境搭建 环境配置&#xff1a; 靶机介绍 包括win7的web端&#xff0c;还有win2003为域成员&#xff0c;域控为win2008 win7内网ip&#xff1a;192.168.157.153 外网ip&#xff1a;192.168.52.143 域成员 win2003 ip 192.168.52.141 域控 win2008 ip 192.168…

基于WEB的仓库管理系统的设计与实现

点击下载源码 基于WEB的仓库管理系统的设计与实现 摘 要 仓库物品的管理是与我们的日常生活息息相关的一个重大问题。随着我国经济飞速的发展&#xff0c;改革开放的不断深入&#xff0c;企业要想在激烈的市场竞争中立于不败之地&#xff0c;要想继续的发展与生存&#xff0…

IDEA报错无效的目标发行版:17

问题描述&#xff1a;由于要接手另外一个项目&#xff0c;之前项目用的jdk17&#xff0c;新项目用的jdk8。需要切换jdk&#xff0c;idea切换之后启动报错 检查之后发现是没切换完全&#xff0c;一共需要切换如下几个地方&#xff1a; 切换前提&#xff1a;电脑上安装了多个版本…

八戒会修特斯拉 气囊电脑 rcm故障代码RCM2_a442_presFrntRDoorOpen

--------------------------------------------------------------------------------------------------------------------------------- -------------------------------------- 作者&#xff1a; 八戒会修特斯拉 -------------------------…

手机在网状态接口如何对接?(一)

一、什么是手机在网状态&#xff1f; 传入手机号码&#xff0c;查询该手机号的在网状态&#xff0c;返回内容有正常使用、停机、在网但不可用、不在网&#xff08;销号/未启用/异常&#xff09;、预销户等多种状态。 二、手机在网状态使用场景&#xff1f; 1.信贷审核&#…

MySQL是怎样运行的——第2章 启动选项和系统变量

文章目录 2.1 在命令行上使用选项2.1.1 选项的长形式和短形式 2.2 配置文件中使用选项2.2.1 配置文件的路径2.2.2 配置文件的内容2.2.3 配置文件的优先级 2.3 命令行和配置文件中启动选项的区别2.4 系统变量2.4.1 简介2.4.2 查看系统变量2.4.3 设置系统变量2.4.4 启动选项和系统…

Java原生序列化与反序列化、URLDNS

配套课件地址&#xff1a;https://blog.csdn.net/mocas_wang/article/details/10762101 1. 概述 1.1 序列化与反序列化 序列化是指把Java代码转化为字节序列的过程&#xff1b;而反序列化时指把字节序列恢复为Java对象的过程。序列化分为两大部分&#xff1a;序列化和反序列化…

mindspore框架实现ckpt模型导出ONNX格式

mindspore框架保存及加载模型 详细流程&#xff1a;昇思-保存及加载模型 关键步骤 关键代码 from mindspore import export, load_checkpoint, load_param_into_net from mindspore import Tensor import numpy as np from MobileNet2GarbageCls.MobileNetv2 import *# 有…

第二证券:商业航天概念再活跃,航天晨光5连板,航新科技等涨停

商业航天概念1日盘中再度活跃&#xff0c;到发稿&#xff0c;航新科技、春晖智控“20cm”涨停&#xff0c;航天雄图涨超10%&#xff0c;航天长峰、航天晨光、星网宇达、航天科技、航天展开等均涨停&#xff0c;航宇微涨近10%。 值得注意的是&#xff0c;航天晨光已接连5个交易…

如何对同一个项目,不同分支,开两个IDEA窗口?

问题&#xff1a;有次我想参考&#xff08;fu zhi&#xff09;某个分支的代码&#xff0c;来写代码&#xff0c;但是打开双击项目的pom文件&#xff0c;会自动打开现在的IDEA窗口&#xff0c;如下&#xff1a; 解决&#xff1a;后面我用Open的方式打开&#xff0c;也是一样的。…