【状压DP】最优配对问题(jzoj 3420)
最优配对问题
jzoj 3420
题目大意:
在平面上有n个点,现在要把他们拼成n/2对,拼接两个点的代价是他们的平面距离,现在问代价总和最小是多少
输入样例
4
8730 9323
-3374 3929
-7890 -6727
1257 4689
输出样例
20366.60
数据范围
2<=N<=20
解题思路#1:
用dfs每一次选1个数和当前数字匹配,如果当前数字选过了,就进入下一层
代码#1:
#include<cmath>
#include<cstdio>
#define min(a,b) (a)<(b)?(a):(b)
using namespace std;
int n,p[30];
double ans,x[30],y[30];
double dis(int a,int b){return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));}//计算
void dfs(int dep,double sum)
{if (dep>n){ans=min(ans,sum);//尝试更新答案return;}if (sum>=ans) return;//无法更新答案了if (p[dep]) dfs(dep+1,sum);//选过就直接下一层else{for (int i=dep+1;i<=n;++i)if (!p[i]){p[i]=1;dfs(dep+1,sum+dis(dep,i));//选一个和它匹配的数p[i]=0;}}
}
int main()
{scanf("%d",&n);for (int i=1;i<=n;++i)scanf ("%lf %lf",&x[i],&y[i]);ans=9999999999.99;dfs(1,0.0);printf("%.2lf",ans);
}
解题思路#2:
用bfs先造出一个状压模型,然后用模型进行状压DP
代码#2:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define min(a,b) (a)<(b)?(a):(b)
using namespace std;
int n,tail=1,q[1<<21];
double x[30],y[30],f[1<<21];
int pd(int x,int y){return x&(1<<y);}
double dis(int a,int b){return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));}
void bfs()//制造模型
{q[1]=0;int h,head=0;while(head<tail){h=q[++head];int i=n-1;for (;i>=0;--i)if (pd(h,i)) break;//找一个最高位的1for (int j=n-1;j>i;--j)//在最高位后面加1q[++tail]=h|(1<<j);}
}
void dp()
{for (int i=1;i<=tail;++i){int s=q[i];int j=n-1;for (;j>=0;--j)if (!pd(s,j)) break;//找最高位的0for (int k=0;k<j;++k)//找一个和它相匹配的数if (!pd(s,k))f[s|(1<<j)|(1<<k)]=min(f[s|(1<<j)|(1<<k)],f[s]+dis(j,k));//状压DP}
}
int main()
{scanf("%d",&n);for (int i=0;i<n;++i)scanf("%lf %lf",&x[i],&y[i]);memset(f,0x7f,sizeof(f));f[0]=0;bfs();dp();printf("%.2lf",f[(1<<n)-1]);//输出
}
【状压DP】最优配对问题(jzoj 3420)相关推荐
- [状压DP][BFS][哈希]JZOJ 3243 Cube
Description 你被困在一个密室里.经过一轮摸索,你在密室里有所发现: 1.密室是一个呈m×n网格的长方形,地面有六个格子被上了色: 2.密室地面部分格子可能有障碍物: 3.密室的某一格有一个 ...
- 【状压DP】剑之修炼(jzoj 2130)
剑之修炼 jzoj 2130 题目大意: 在一个位置上有一个人,同时还有NNN(N⩽10N \leqslant 10N⩽10)个怪物,这个人会不停地释放技能,技能可以瞬间杀死周围8个格子上的怪物,行走 ...
- Codeforces Beta Round #8 C. Looking for Order 状压dp
题目链接: http://codeforces.com/problemset/problem/8/C C. Looking for Order time limit per test:4 second ...
- UVA10296 Jogging Trails(中国邮递员问题)(欧拉回路、一般图最大权匹配 / 状压DP)
整理的算法模板合集: ACM模板 目录 思路 UVA10296 Jogging Trails 题目翻译: 给你n个点,m条无向边,每条边有一定的距离数值,构造成一个连通图.问从任意一点出发,遍历所有的 ...
- 【思维题 状压dp】APC001F - XOR Tree
可能算是道中规中矩的套路题吧-- Time limit : 2sec / Memory limit : 256MB Problem Statement You are given a tree wit ...
- BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4042 (Luogu) https://www.luogu.org/prob ...
- P1433 吃奶酪(状压dp)
洛谷 / 题目列表 / 题目详情 P1433 吃奶酪 提交 23.28k 通过 9.30k 时间限制 1.00s 内存限制 125.00MB 题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问 ...
- CodeForces - 1550E Stringforces(二分+状压dp)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,只包含前 kkk 个小写字母以及通配符 ???,现在可以将通配符替换成任意的前 kkk 个字母中的一个.设 f[i]f[i]f[i] 为 ...
- 中石油训练赛 - Watch Later(状压dp)
题目链接:点击查看 题目大意: 给出一个长度为 n 的字符串,字符串中共有 k 种不同的字符,现在问删除掉所有字符的最小操作数,对于每种字符需要确定一个先后顺序,每次需要删除掉当前所有的这种字符才能去 ...
最新文章
- linux 文件系统及磁盘管理
- Linux常用命令(第二版) --文件管理命令
- 计算机语言python发音_Python如何像scratch一样朗读文字?
- 疯狂软件对Oracle放弃Java EE的看法
- 转载 树莓派vnc 教程
- SpringBoot动态切换数据源-快速集成多数据源的启动器
- R语言ETL工程:插入与合并(add/bind)
- 开源 CMS系统 / SNS系统 / BBS系统
- SQL 经典练习题 + 答案
- 方差分析的SPSS实现
- WEB UI设计尺寸规范
- origin 一键导出文件夹中所有图形
- mysql chunk_【MySQL参数】-innodb_buffer_pool_chunk_size
- 台式计算机怎样能搜无线连接,台式电脑怎么设置无线网络!台式电脑也能上wifi...
- 网络上怎么赚钱?这3个赚钱方式目前最稳妥!
- Unity网格系统(1)网格生成
- kube-apiserver源码-动态准入控制 admission webhook
- 【转载】linux top命令及参数详解
- 最新百家姓-你排老几
- Oracle Demo库默认用户/密码为什么叫Scott/Tigger?
热门文章
- c语言修仙受控可看吗,强推三本神奇到爆的小说,c语言修仙,程序员与修真会擦出什么火花...
- oracle asm 配置失败,Oracle ASMLib安装与配置
- relation does not exist报错是什么意思_为什么Zookeeper天生就是一副分布式锁的胚子?...
- C++ 学习之旅(15)——继承inheritance
- [Qt入门]模态和非模态对话框创建
- 洛谷 P1162 填涂颜色-dfs染色法
- 并发协作模型“生产者/消费者模式“
- JAVA基础知识+基础代码
- c++ 位运算_C语言之运算符
- Leetcode 1109.航班预定统计 差分