关于没那么启发式的启发式合并写法

本文探讨了真实与虚假的树上启发式合并算法,详细介绍了通过轻儿子和重儿子处理来优化时间与空间复杂度的技术。虚假启发式合并虽然看似不合理,但其时间复杂度表现优秀,代码更简洁,空间复杂度亦有所优化。

真实的树上启发式合并:先dfs一遍,处理出轻儿子和重儿子,然后先处理轻儿子,再处理重儿子,最后把轻儿子合并进重儿子。

虚假的树上启发式合并:大的合进小的.jpg

然而虚假的启发式合并的时间复杂度意外的优秀,很意外的能水(稳?)过很多题。

比起真实的启发式合并少了蛮多代码,何乐而不为呢。

同时空间复杂度居然也优化了不少,swap操作让全局map内元素少了非常非常多。

cf600e:

#include<bits/stdc++.h>

using namespace std;
const long long mod = 1e9 + 7;
typedef long long ll;

const int maxn = 1e5 + 5;

int n, u, v, cor[maxn];
ll ans[maxn];
int id[maxn], tot;
unordered_map<int, int> mp[maxn];
map<int, ll> cnt[maxn];
vector<int> G[maxn];

void merge(int &x, int &y) {
    if (mp[y].size() > mp[x].size()) {
        swap(x, y);
    }
    for (auto &e: mp[y]) {
        cnt[x][mp[x][e.first]] -= e.first;
        mp[x][e.first] += e.second;
        cnt[x][mp[x][e.first]] += e.first;
    }
}

void dfs(int x, int fa) {
    id[x] = ++tot;
    mp[id[x]][cor[x]] = 1;
    cnt[id[x]][mp[id[x]][cor[x]]] = cor[x];
    for (int i = 0; i < G[x].size(); ++i) {
        int v = G[x][i];
        if (v == fa) {
            continue;
        }
        dfs(v, x);
        merge(id[x], id[v]);
    }
    ans[x] = cnt[id[x]].rbegin()->second;
}


int main() {
    ios::sync_with_stdio(0);
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> cor[i];
    }
    for (int i = 1; i < n; ++i) {
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1, 1);
    for (int i = 1; i <= n; ++i) {
        cout << ans[i] << ' ';
    }
    return 0;
}

【四轴飞行器】非线性三自由四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由四轴飞行器模拟器的研究展开,重点介绍基于Matlab代码实现的四轴飞行器动力学建模与仿真方法。研究构建了考虑非线性特性的飞行器数学模型,涵盖姿态动力学与运动学方程,实现了三自由(滚转、俯仰、偏航)的精确模拟。文中详细阐述了系统建模过程、控制算法设计思路及仿真结果分析,帮助读者深入理解四轴飞行器的飞行动力学特性与控制机制;同时,该模拟器可用于算法验证、控制器设计与教学实验。; 适合人群:具备一定自动控制理论基础Matlab编程能力的高校学生、科研人员及无人机相关领域的工程技术人员,尤其适合从事飞行器建模、控制算法开发的研究生初级研究人员。; 使用场景及目标:①用于四轴飞行器非线性动力学特性的学习与仿真验证;②作为控制器(如PID、LQR、MPC等)设计与测试的仿真平台;③支持无人机控制系统教学与科研项目开发,提升对姿态控制与系统仿真的理解。; 阅读建议:建议读者结合Matlab代码逐模块分析,重点关注动力学方程的推导与实现方式,动手运行并调试仿真程序,以加深对飞行器姿态控制过程的理解。同时可扩展为六自由模型或加入外部干扰以增强仿真真实性。
基于分布式模型预测控制DMPC的多智能体点对点过渡轨迹生成研究(Matlab代码实现)内容概要:本文围绕“基于分布式模型预测控制(DMPC)的多智能体点对点过渡轨迹生成研究”展开,重点介绍如何利用DMPC方法实现多智能体系统在复杂环境下的协同轨迹规划与控制。文中结合Matlab代码实现,详细阐述了DMPC的基本原理、数学建模过程以及在多智能体系统中的具体应用,涵盖点对点转移、避障处理、状态约束与通信拓扑等关键技术环节。研究强调算法的分布式特性,提升系统的可扩展性与鲁棒性,适用于多无人机、无人车编队等场景。同时,文档列举了大量相关科研方向与代码资源,展示了DMPC在路径规划、协同控制、电力系统、信号处理等多领域的广泛应用。; 适合人群:具备一定自动化、控制理论或机器人学基础的研究生、科研人员及从事智能系统开发的工程技术人员;熟悉Matlab/Simulink仿真环境,对多智能体协同控制、优化算法有一定兴趣或研究需求的人员。; 使用场景及目标:①用于多智能体系统的轨迹生成与协同控制研究,如无人机集群、无人驾驶车队等;②作为DMPC算法学习与仿真实践的参考资料,帮助理解分布式优化与模型预测控制的结合机制;③支撑科研论文复现、毕业设计或项目开发中的算法验证与性能对比。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注DMPC的优化建模、约束处理与信息交互机制;按文档结构逐步学习,同时参考文中提及的路径规划、协同控制等相关案例,加深对分布式控制系统的整体理解。
# -*- coding:utf-8 -*- class Solution: def salvePuzzle(self, init, targ): ''' 求解8数码问题 参数: init - 初始状态 例如'123046758' targ - 目标状态 均为'012345678' 返回: clf - 由udlr组成的移动路径字符串 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# clf = '' state_open = [] state_close = [] state_open.append([init,99,'test',init,0]) fn = 2 flag = 1 while True: cur_state = state_open.pop(0) state_close.append(cur_state) if cur_state[0] == targ : while 1: clf += cur_state[2] if cur_state[3] == init: break for id,item in enumerate(state_close[1:]): if item[0] == cur_state[3]: cur_state = item return clf[::-1] i = cur_state[0].find('0') flag = 1 if str(i) not in '036': tmp_map = self.moveMap(cur_state[0],i,i-1) if tmp_map not in [tmp[0] for tmp in state_close]: for id,item in enumerate(state_open): if item[0] == tmp_map: if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn: state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'l',cur_state[0],cur_state[4]+fn] flag = 0 break break if flag == 1: state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'l',cur_state[0],cur_state[4]+fn]) flag = 1 if str(i) not in '258': tmp_map = self.moveMap(cur_state[0],i,i+1) if tmp_map not in [tmp[0] for tmp in state_close]: for id,item in enumerate(state_open): if item[0] == tmp_map: if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn: state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'r',cur_state[0],cur_state[4]+fn] flag = 0 break if flag ==1: state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'r',cur_state[0],cur_state[4]+fn]) flag = 1 if i-3>=0: tmp_map = self.moveMap(cur_state[0],i,i-3) if tmp_map not in [tmp[0] for tmp in state_close]: for id,item in enumerate(state_open): if item[0] == tmp_map: if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn: state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'u',cur_state[0],cur_state[4]+fn] flag = 0 break if flag ==1: state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'u',cur_state[0],cur_state[4]+fn]) flag = 1 if i+3<=8: tmp_map = self.moveMap(cur_state[0],i,i+3) if tmp_map not in [tmp[0] for tmp in state_close]: for id,item in enumerate(state_open): if item[0] == tmp_map: if item[1] + item[4] > self.calcDistH(tmp_map,targ) + cur_state[4] + fn: state_open[id] = [tmp_map,self.calcDistH(tmp_map,targ),'d',cur_state[0],cur_state[4]+fn] flag = 0 break if flag ==1: state_open.append([tmp_map,self.calcDistH(tmp_map,targ),'d',cur_state[0],cur_state[4]+fn]) state_open.sort(key=lambda x : x[1] + x[4]) #********** End **********# def calcDistH(self, src_map, dest_map): '''启发式函数h(n) 参数: src_map - 当前8数码状态 dest_map - 目标8数码状态 返回: clf - 当前状态到目标状态的启发式函数 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# distance = 0 for i in range(9): if src_map[i] != '0': current_pos = i target_pos = dest_map.index(src_map[i]) distance += abs(current_pos//3 - target_pos//3) + abs(current_pos % 3 - target_pos % 3) return distance #current_pos // 3 表示的是current_pos所在的行 #current_pos % 3 表示的是current_pos所在的列 #以上式子表示的就是曼哈顿距离 #********** End **********# def moveMap(self, cur_map, i, j): '''状态转换(交换位置ij) 参数: cur_map - 当前8数码状态 i - 当前8数码状态中空格0的位置索引 j - 将空格0的位置i移动到位置j,位置j移动到位置i 返回: clf - 新的8数码状态 ''' #请在这里补充代码,完成本关任务 #********** Begin **********# clf = list(cur_map) #将原来的数码状态转换为列表 lst[i],lst[j] = lst[j],lst[i] #进行交换 return ''.join(clf) #将交换后的列表合并 并返回 #********** End **********#
10-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值