学习动态规划DP(三)最优匹配问题

本文介绍了如何使用动态规划解决最优匹配问题,该问题涉及在有限数量的点中找到最佳配对,使得所有配对之间的距离之和最小。通过二进制表示点集并逐步增加点的数量来求解,最终得到全局最优解。文章还提供了学习过程中的理解和代码实现。
摘要由CSDN通过智能技术生成

前言:《算法竞赛入门经典》中将最优匹配问题归在复杂状态的动态规划下,第一次看的时候完全不懂…,隔几天后再看顿时豁然开朗,快点写下笔记和总结。在此问题之前还有树上的动态规划,以后再总结一下。

问题描述:空间里有n个点P0,P1,…,Pn-1,你的任务是把它们配成n/2对(n是偶数),使得每个点恰好在一个点对中。所有点对中两点的距离之和应尽量小。其中 n≤20。

要匹配的点最多才20个,所以这里可以把所有点看成一个点集,并且可以用二进制表示方法来表示这个集合。(学的时候感觉,太强了,太好用了。但需要先明白位运算)。
如:01101 表示第 0,2,3个元素存在于集合中,相当于全集的子集表示。由于二进制为从0开始,所以上述的点编号也从0开始。
用二进制表示的好处:便于寻找那些点在集合中,便于划分子集

思路:要求的是所有点的最优匹配,我们把大问题划分为小问题,再根据小问题所求 的解来求解大问题;
先求解任意一个只含有两个点的子集,求这些子集的最优解(即求解 点 i 到
全集S中其他点的距离的最小值);
再求解任意一个只含有四个点的子集,因为只含有两个点的子集已经计算过。
所以我们在原来计算过的基础上,在S中寻找其他的两个点,计算它们的距离。
再将这四个点并成一个集合,同样地要取最小解。
(即若原来0,1两点已经匹配好,那我们要求的是,所有包含0和1且含有四个点
的集合的最优解)
这样依次类推,直到求得全集的最优解 。
(我们每次求得的解都是,含有某些配对的集合的最优解)

定义状态:d[s] 表示 点集s的最优匹配,则状态方程表示为:
d[s] = min( d[s] , dist(i,j)+d[s^(i<< i )^(1<< j )];
其中s^(1<< i)^(1<< j) 表示 集合s除去 i和j 的子集;
相当于一种构造集合的方式:通过往集合中添加一对匹配的点构造集合(一开始为空集)。

下面是通过紫书学习的代码,注释的都是我学习时一点点弄懂的;原书上代码有一点小错误,有读者在看原书的话注意一下。

#include<iostream>
#include<cmath>
using namespace std;

const int N = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值