[HAOI2008]移动玩具(状压&带权二分图)
题目描述
• 一个 4 × 4 的 0/1 矩阵
• 每次可以交换相邻两个元素
• 求从初始状态到目标状态的最小交换次数
输入格式
前四行,每行一个长为 4 的 0/1 字符串,描述初始状态。
后四行,每行一个长为 4 的 0/1 字符串,描述目标状态。
输出格式
一行一个数,表示最小交换次数。
样例输入
1111
0000
1110
0010
1010
0101
1010
0101
样例输出
4
solution:
不得不说这确实是道好题,而且难度适中。看到此题为0/1字符串并且数据规模小(但也太小了吧)可以想到状压因为只有16个格子,所以不同的局面最多只有2^16 = 65536 个,不过01数量对等所以准确的说应该只有12870 个。所以我们Hash :把 16 个格子的 0/1 压成一个数字就好了。
但如果仔细分析一下题目性质,我们可以发现一些不同:我们在读入目标棋盘的时候,把当前位置的数和目标棋盘进行比较,如果不一样,比如当前是1,目标是0,那么我们就把当前位置加入move队列里去,否则加入got队列里去。move和got的队列肯定是一样长的。然后我们将这两个队列里的元素进行匹配,把move里的一个位置上的1移到got里的一个位置上去,该操作需要的步数,就是这两个位置的曼哈顿距离。
这样我们可以搜索来枚举匹配方案,当然也可以直接带权二分图匹配(这样可以应对数据范围很大的题型)
code:
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
using namespace std;
struct su{
int x,y;
}a[101],b[101];
int n,m,t1,t2,ans=inf;
bool c[11][11];
bool d[11][11];
int s[101][101];
bool use[101];
inline int qr(){ char ch;
while((ch=getchar())<'0'||ch>'9');
return ch^48;
}
inline void dfs(int t,int tot){
if(t==t1+1){
ans=tot;
return ;
}
for(rg i=1;i<=t2;++i){
if(use[i]||tot+s[t][i]>ans)
continue;
use[i]=1;
dfs(t+1,tot+s[t][i]);
use[i]=0;
}
}
int main(){
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
n=m=4;
for(rg i=0;i<n;++i)
for(rg j=0;j<m;++j)
c[i][j]=qr();
for(rg i=0;i<n;++i){
for(rg j=0;j<m;++j){
d[i][j]=qr();
if(c[i][j]^d[i][j]){
if(c[i][j]){
a[++t1].x=i;
a[t1].y=j;
}else{
b[++t2].x=i;
b[t2].y=j;
}
}
}
} rg x,y;
for(rg i=1;i<=t1;++i){
for(rg j=1;j<=t2;++j){
x=a[i].x-b[j].x;
y=a[i].y-b[j].y;
if(x<0)x=-x;
if(y<0)y=-y;
s[i][j]=x+y;
}
} dfs(1,0);
printf("%d",ans);
return 0;
}
[HAOI2008]移动玩具(状压&带权二分图)的更多相关文章
- bzoj1054: [HAOI2008]移动玩具 状压+爆搜即可
题意:在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初的玩具状态 ...
- [HAOI2008]移动玩具 状压
发现自己只会打状压了. 233333 不需要考虑是否会被挡,所以直接dp #include<cstdio> #include<cstring> #include<iost ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
- POJ 2195 Going Home (带权二分图匹配)
POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...
- Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)
Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...
- 运动员最佳匹配问题 KM算法:带权二分图匹配
题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...
- POJ 2195 Going Home | 带权二分图匹配
给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...
- KM(Kuhn-Munkres)算法求带权二分图的最佳匹配
KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...
- 费用流模板(带权二分图匹配)——hdu1533
/* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 1000 ...
随机推荐
- dp算法之平安果路径问题c++
前文:https://www.cnblogs.com/ljy1227476113/p/9563101.html 在此基础上更新了可以看到行走路径的代码. 代码: #include <iostre ...
- CSAPP lab2 二进制拆弹 binary bombs phase_5
给出对应于7个阶段的7篇博客 phase_1 https://www.cnblogs.com/wkfvawl/p/10632044.htmlphase_2 https://www.cnblogs. ...
- LeetCode 606. Construct String from Binary Tree根据二叉树创建字符串 (C++)
题目: You need to construct a string consists of parenthesis and integers from a binary tree with the ...
- Linux内核分析——第一周学习笔记20135308
第一周 计算机是如何工作的 第一节 存储程序计算机工作模型 1.冯·诺依曼结构模型:冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构.程序指令存储地址和数据存储 ...
- 一篇关于spring ioc 依赖注入3种方式的文章引用
今天看到一篇spring ioc 容器依赖注入3种方式的文章,为了方便后面的复习,在此引用别人的文章,查看请戳我.
- MySQL 字符串截取函数
MySQL 字符串截取函数:left(), right(), substring(), substring_index().还有 mid(), substr().其中,mid(), substr() ...
- Windows 使用 StarWind 创建的 Oracle RAC环境 异常关机之后的处理过程
创建好了 虚拟机之后发现 偶尔会出现 蓝屏重启的现象, 这个时候 需要进行 异常处理 确定虚拟机已经开机之后 1. 打开iscsi的连接设备, 确认 iscsi的正常连接到虚拟机的 存储设备 注意 r ...
- Oracle client 使用 .net程序连接 数据库时 出现 8.1.7 的解决办法
1. GS产品 连接oracle数据库时出现错误图示 2. 其实解决这个问题的办法很简单 一般是 修改一下 Oracle的app 目录的权限 最简单的办法是增加 everyone 权限 然后重启机器即 ...
- Oracle 导入单表数据
1. 测试一下 删除某一张表,然后 通过 expdp 数据库泵的备份来恢复数据. 测试过程 ) from bizlog COUNT() ---------- 151 drop table bizlog ...
- Tree Constructing CodeForces - 1003E(构造)
题意: 就是让构造一个直径为d的树 每个结点的度数不能超过k 解析: 先构造出一条直径为d的树枝 然后去遍历这条树枝上的每个点 为每个点在不超过度数和直径的条件下添加子嗣即可 #include & ...