kings(骑士)解题报告
kings(骑士)
Time Limit5000 ms Memory Limit131072 KBytes
Description
用字符矩阵来表示一个8x8的棋盘,'.'表示是空格,'P'表示人质,'K'表示骑士。 每一步,骑士可以移动到他周围的8个方格中的任意一格。如果你移动到的格子中有人质(即'P'),你将俘获他。但不能移到出棋盘或当前是'K'的格子中。 请问最少要移动多少步骑士才能俘获所有的人质。
Input Format
第一行一个整数N(<=5),表示有多少个棋盘。即多组测试数据。 每一组有8行,每行8个字符。字符只有'.',大写'P',大写'K'三种字符。'P'和'K'的个数范围都在[1,10]。
Output Format
有N行,每行只一个整数,相应棋盘俘获全部人质所需要的最少步数。
Sample Input
2
P......P
........
........
........
...KK...
........
........
P......P
.....P.P
..K....P
....K...
..PP...P
...K..KK
........
K.......
KP.K....
Sample Output
20
9
Solution
分析:1.p,k<=10考虑用状压
2.每个骑士的路径独立互不影响(若路径相交必然不是最优解)
基于以上两点,可以先求出每个骑士拯救集合S(状压2进制表示)的最小步数,然后通过这个求出前i个骑士拯救集合S的最小步数
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x7f7f7f7f
using namespace std; int T,p[],k[],d[][];
int f1[][][<<],f2[][<<]; void ycl(){
for (int xa=;xa<=;++xa)
for (int ya=;ya<=;++ya)
for (int xb=;xb<=;++xb)
for (int yb=;yb<=;++yb){
int x=(xa-)*+ya,y=(xb-)*+yb;
int dex=abs(xa-xb),dey=abs(ya-yb);
int t=min(dex,dey);
d[x][y]=t+(dex-t)+(dey-t);
}
} int main(){
ycl();
for (scanf("%d",&T);T;--T){
memset(f1,0x7f,sizeof f1);
memset(f2,0x7f,sizeof f2);
p[]=k[]=;
for (int i=;i<=;++i)
for (int j=;j<=;++j){
char c=getchar();
while (c!='.'&&c!='P'&&c!='K') c=getchar();
if (c=='P') p[++p[]]=(i-)*+j;
if (c=='K') k[++k[]]=(i-)*+j;
}
for (int i=;i<=k[];++i){
for (int j=;j<=p[];++j)
f1[i][j][<<(j-)]=d[k[i]][p[j]];
for (int s=;s<(<<p[]);++s)
for (int j=;j<=p[];++j)
if (s&(<<(j-)))
for (int l=;l<=p[];++l)
if (!(s&(<<(l-))))
f1[i][l][s|(<<(l-))]=min(f1[i][l][s|(<<(l-))],f1[i][j][s]+d[p[j]][p[l]]);
}
for (int i=;i<=k[];++i)
for (int s=;s<(<<p[]);++s)
for (int j=;j<=p[];++j)
f1[i][][s]=min(f1[i][][s],f1[i][j][s]);
f2[][]=;
for (int i=;i<=k[];++i){
f2[i][]=;
for (int s=;s<(<<p[]);++s){
f2[i][s]=f2[i-][s];
for (int ss=;ss<s;++ss)
if ((s|ss)==s&&(f2[i-][ss]!=INF&&f1[i][][s^ss]!=INF))
f2[i][s]=std::min(f2[i][s],f2[i-][ss]+f1[i][][s^ss]);
}
}
printf("%d\n",f2[k[]][(<<p[])-]);
}
}
以上是标解,下面提供一种(蒟蒻)的做法
我们发现每个骑士只有两种状态:1.在初始位置 2.在某个人质的位置上
每个人质有三种状态:1.没被拯救 2.已经被拯救 3.被拯救且有骑士在这个位置
所以 用f[s1][s2]表示人质状态为s1,骑士的状态为s2的最少步数
每次转移可以将s1中的骑士走出去拯救人质或将s2中在初始位置的骑士走出去拯救人质
#include<cstdio>
#include<cstring>
#include<algorithm> short int o3[][];
short int p[],k[];
short int T,A,B,ans,pw[],d[][],f[<<][]; inline void dfs(int s1,int s2){
if (f[s1][s2]+(p[]-o3[][s2]-o3[][s2])>=ans) return;
if (o3[][s2]+o3[][s2]==p[]){
ans=std::min(ans,f[s1][s2]);
return;
}
for (int i=;i<p[];++i)
if (!((s2/pw[i])%)){
for (int j=;j<p[];++j)
if (((s2/pw[j])%)==){
int t1=s1,t2=s2-pw[j]+pw[i]*;
if (f[t1][t2]>f[s1][s2]+d[p[j+]][p[i+]])
f[t1][t2]=f[s1][s2]+d[p[j+]][p[i+]],dfs(t1,t2);;
}
for (int j=;j<k[];++j)
if (s1&(<<j)){
int t1=s1^(<<j),t2=s2+pw[i]*;
if (f[t1][t2]>f[s1][s2]+d[k[j+]][p[i+]])
f[t1][t2]=f[s1][s2]+d[k[j+]][p[i+]],dfs(t1,t2);
}
}
} inline void csh(){
memset(f,0x7f,sizeof f);
p[]=k[]=;
for (int i=;i<=;++i)
for (int j=;j<=;++j){
char c=getchar();
while (c!='.'&&c!='P'&&c!='K') c=getchar();
if (c=='P') p[++p[]]=(i-)*+j;
if (c=='K') k[++k[]]=(i-)*+j;
}
A=(<<(k[]))-;
f[A][]=;
ans=d[k[]][p[]];
for (int i=;i<=p[];++i) ans+=d[p[i-]][p[i]];
} inline void ycl(){
for (int xa=;xa<=;++xa)
for (int ya=;ya<=;++ya)
for (int xb=;xb<=;++xb)
for (int yb=;yb<=;++yb){
int x=(xa-)*+ya,y=(xb-)*+yb,t;
int dex=std::abs(xa-xb),dey=std::abs(ya-yb);
t=std::min(dex,dey);
d[x][y]=d[y][x]=t+(dex-t)+(dey-t);
}
int maxs=;
for(int i=;i<;++i) maxs+=pw[i]*;
for (int i=;i<=maxs;++i)
for (int j=;j<;++j)
if ((i/pw[j])%)
++o3[(i/pw[j])%-][i];
} int main(){
pw[]=;
for (int i=;i<;++i) pw[i]=pw[i-]*;
ycl();
for (scanf("%d",&T);T;--T){
csh();
dfs(A,);
printf("%d\n",ans);
}
}
kings(骑士)解题报告的更多相关文章
- 洛谷 P2607 [ZJOI2008]骑士 解题报告
P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...
- [BZOJ1040] [ZJOI2008]骑士 解题报告
Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
随机推荐
- .net core webapi通过中间件获取请求和响应内容
本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中: 这里不详细介绍日志文件的使用.你可以自己接入NLog,log4net,Exceptionle ...
- 矩量母函数(Moment Generating Function,mgf,又称:动差生成函数)
在统计学中,矩又被称为动差(Moment).矩量母函数(Moment Generating Function,简称mgf)又被称为动差生成函数. 称exp(tξ)的数学期望为随机变量ξ的矩量母函数,记 ...
- HDU2476 String painter(DP)
题目 String painter 给出两个字符串s1,s2.对于每次操作可以将 s1 串中的任意一个子段变成另一个字符.问最少需要多少步操作能将s1串变为s2串. 解析 太妙了这个题,mark一下. ...
- python检测远程udp端口是否打开的代码
研发过程,把开发过程较好的代码收藏起来,如下的代码内容是关于python检测远程udp端口是否打开的代码,希望对各朋友有较大帮助. import socketimport threadingimpor ...
- js获取任意一天的0点和23:59:59时间
最近写代码时,需要获取任意一天的起始和结束时间,0点和23:59:59这两个时间的时间戳 使用了setHours() 方法 setHours() 方法用于设置指定的时间的小时字段 1. 获取当天开始时 ...
- nodejs puppeteer linux(centos)环境部署以及用puppeteer简单截图
1.安装Node环境 如果有安装Node请忽略第1点 #下载cd /usr/local/srcwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-l ...
- Xshell6和Xftp6 破解免安装版,无窗口多开限制
免安装无窗口限制破解版 链接:https://pan.baidu.com/s/1wpFE499qoTjqHrPdQmTn4g提取码:2xcn 如上面的链接失效,可使用以下的链接: https://pa ...
- linux文件常用操作
建立目录:mkdir mkdir -p [目录名] -p 递归创建 命令英文原意: make directories 切换所在目录:cd cd [目录] cd ~ 进入当前用户的家目录 cd c ...
- Cisco网络模拟器踩坑记录
1.在我们新建一个拓扑图的时候,选择设备之间的连线种类有时会导致线路不通的情况(两个端口上为红色点)这时候建议拆除这条线后选择闪电标记 的万能线帮助我们自动创建连线(这时就能根据它显示的线条种类得知应 ...
- KMP算法的时间复杂度与next数组分析
一.什么是 KMP 算法 KMP 算法是一种改进的字符串匹配算法,用于判断一个字符串是否是另一个字符串的子串 二.KMP 算法的时间复杂度 O(m+n) 三.Next 数组 - KMP 算法的核心 K ...