CF1065D
如果不喜欢过长代码的看官,请移步其他题解...
这题其实思想极其简单:
棋盘问题常见的算法都比较暴力,常用的有搜索和状压dp
而这道题显然没啥能状压的,所以我们考虑搜索
但是仅仅搜索是不够的,因为有极大的可能搜到死...
所以我们引入记忆化
设状态f[i][j][k][0/1/2]代表目前在点(i,j)处,上一个到达的点(注意是达成要求而非经过)的编号为k,目前的棋子种类为1/2/3时,所需要的最小代价
当然这还不够,我们还要保证在代价最小时更换棋子次数最小,所以我们再用状态g[i][j][k][0/1/2]更新,下标含义与上述相同,表示对应状态所需的最小棋子更换次数
注意优先更新f,在保证f合法的情况下维护g
然后用bfs更新即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <vector>
#include <ctime>
#include <set>
#include <deque>
#include <bitset>
using namespace std;
int dp[][][][];
int g[][][][];
int xp[],yp[];
int maps[][];
int dir[][]={{,},{,},{,-},{-,},{-,-},{-,-},{,-},{-,}};
int n;
bool check(int x,int y)
{
if(x>&&x<=n&&y>&&y<=n)
{
return ;
}
return ;
}
void bfs()
{
memset(dp,0x3f,sizeof(dp));
memset(g,0x3f,sizeof(g));
dp[xp[]][yp[]][][]=;//车
dp[xp[]][yp[]][][]=;//马
dp[xp[]][yp[]][][]=;//象
g[xp[]][yp[]][][]=;
g[xp[]][yp[]][][]=;
g[xp[]][yp[]][][]=;
queue <int> Qx,Qy,Qz,Qv;
for(int i=;i<=;i++)
{
Qx.push(xp[]);
Qy.push(yp[]);
Qz.push(i);
Qv.push();
}
while(!Qx.empty())
{
int ux=Qx.front();
int uy=Qy.front();
int uz=Qz.front();
int uv=Qv.front();
Qx.pop();
Qy.pop();
Qz.pop();
Qv.pop();
if(uv==n*n)
{
continue;
}
if(uz==)
{
for(int i=;i<=n;i++)
{
if(i==uy)
{
continue;
}
if(maps[ux][i]==uv+)
{
if(dp[ux][i][uv+][uz]>dp[ux][uy][uv][uz]+)
{
dp[ux][i][uv+][uz]=dp[ux][uy][uv][uz]+;
g[ux][i][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(ux);
Qy.push(i);
Qz.push(uz);
Qv.push(uv+);
}else if(dp[ux][i][uv+][uz]==dp[ux][uy][uv][uz]+&&g[ux][i][uv+][uz]>g[ux][uy][uv][uz])
{
g[ux][i][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(ux);
Qy.push(i);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[ux][i][uv][uz]>dp[ux][uy][uv][uz]+)
{
dp[ux][i][uv][uz]=dp[ux][uy][uv][uz]+;
g[ux][i][uv][uz]=g[ux][uy][uv][uz];
Qx.push(ux);
Qy.push(i);
Qz.push(uz);
Qv.push(uv);
}else if(dp[ux][i][uv][uz]==dp[ux][uy][uv][uz]+&&g[ux][i][uv][uz]>g[ux][uy][uv][uz])
{
g[ux][i][uv][uz]=g[ux][uy][uv][uz];
Qx.push(ux);
Qy.push(i);
Qz.push(uz);
Qv.push(uv);
}
}
}
for(int i=;i<=n;i++)
{
if(i==ux)
{
continue;
}
if(maps[i][uy]==uv+)
{
if(dp[i][uy][uv+][uz]>dp[ux][uy][uv][uz]+)
{
dp[i][uy][uv+][uz]=dp[ux][uy][uv][uz]+;
g[i][uy][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(i);
Qy.push(uy);
Qz.push(uz);
Qv.push(uv+);
}else if(dp[i][uy][uv+][uz]==dp[ux][uy][uv][uz]+&&g[i][uy][uv+][uz]>g[ux][uy][uv][uz])
{
g[i][uy][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(i);
Qy.push(uy);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[i][uy][uv][uz]>dp[ux][uy][uv][uz]+)
{
dp[i][uy][uv][uz]=dp[ux][uy][uv][uz]+;
g[i][uy][uv][uz]=g[ux][uy][uv][uz];
Qx.push(i);
Qy.push(uy);
Qz.push(uz);
Qv.push(uv);
}else if(dp[i][uy][uv][uz]==dp[ux][uy][uv][uz]+&&g[i][uy][uv][uz]>g[ux][uy][uv][uz])
{
g[i][uy][uv][uz]=g[ux][uy][uv][uz];
Qx.push(i);
Qy.push(uy);
Qz.push(uz);
Qv.push(uv);
}
}
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]==dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]==dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
}else if(uz==)//马
{
for(int i=;i<;i++)
{
int tx=ux+dir[i][];
int ty=uy+dir[i][];
if(tx<=||tx>n||ty<=||ty>n)
{
continue;
}
if(maps[tx][ty]==uv+)
{
if(dp[tx][ty][uv+][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv+][]=dp[ux][uy][uv][]+;
g[tx][ty][uv+][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv+);
Qz.push();
}else if(dp[tx][ty][uv+][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv+][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[tx][ty][uv][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv][]=dp[ux][uy][uv][]+;
g[tx][ty][uv][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv);
Qz.push();
}else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv);
}
}
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]==dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]==dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
}else if(uz==)
{
for(int i=;i<=n;i++)
{
int tx=ux+i;
int ty=uy+i;
if(check(tx,ty))
{
if(maps[tx][ty]==uv+)
{
if(dp[tx][ty][uv+][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv+][]=dp[ux][uy][uv][]+;
g[tx][ty][uv+][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv+);
Qz.push();
}else if(dp[tx][ty][uv+][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv+][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[tx][ty][uv][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv][]=dp[ux][uy][uv][]+;
g[tx][ty][uv][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv);
Qz.push();
}else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}
}
tx=ux+i;
ty=uy-i;
if(check(tx,ty))
{
if(maps[tx][ty]==uv+)
{
if(dp[tx][ty][uv+][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv+][]=dp[ux][uy][uv][]+;
g[tx][ty][uv+][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv+);
Qz.push();
}else if(dp[tx][ty][uv+][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv+][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[tx][ty][uv][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv][]=dp[ux][uy][uv][]+;
g[tx][ty][uv][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv);
Qz.push();
}else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv);
}
}
}
tx=ux-i;
ty=uy+i;
if(check(tx,ty))
{
if(maps[tx][ty]==uv+)
{
if(dp[tx][ty][uv+][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv+][]=dp[ux][uy][uv][]+;
g[tx][ty][uv+][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv+);
Qz.push();
}else if(dp[tx][ty][uv+][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv+][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[tx][ty][uv][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv][]=dp[ux][uy][uv][]+;
g[tx][ty][uv][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv);
Qz.push();
}else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv);
}
}
}
tx=ux-i;
ty=uy-i;
if(check(tx,ty))
{
if(maps[tx][ty]==uv+)
{
if(dp[tx][ty][uv+][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv+][]=dp[ux][uy][uv][]+;
g[tx][ty][uv+][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv+);
Qz.push();
}else if(dp[tx][ty][uv+][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv+][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv+][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv+);
}
}else
{
if(dp[tx][ty][uv][]>dp[ux][uy][uv][]+)
{
dp[tx][ty][uv][]=dp[ux][uy][uv][]+;
g[tx][ty][uv][]=g[ux][uy][uv][];
Qx.push(tx);
Qy.push(ty);
Qv.push(uv);
Qz.push();
}else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
{
g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
Qx.push(tx);
Qy.push(ty);
Qz.push(uz);
Qv.push(uv);
}
}
}
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
if(dp[ux][uy][uv][]>dp[ux][uy][uv][uz]+)
{
dp[ux][uy][uv][]=dp[ux][uy][uv][uz]+;
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}else if(dp[ux][uy][uv][]==dp[ux][uy][uv][uz]+&&g[ux][uy][uv][]>g[ux][uy][uv][uz]+)
{
g[ux][uy][uv][]=g[ux][uy][uv][uz]+;
Qx.push(ux);
Qy.push(uy);
Qz.push();
Qv.push(uv);
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
scanf("%d",&maps[i][j]);
xp[maps[i][j]]=i;
yp[maps[i][j]]=j;
}
}
bfs();
int ans=0x3f3f3f3f;
int ret=0x3f3f3f3f;
for(int i=;i<=;i++)
{
if(ans>dp[xp[n*n]][yp[n*n]][n*n][i])
{
ans=dp[xp[n*n]][yp[n*n]][n*n][i];
ret=g[xp[n*n]][yp[n*n]][n*n][i];
}else if(ret>g[xp[n*n]][yp[n*n]][n*n][i]&&ans==dp[xp[n*n]][yp[n*n]][n*n][i])
{
ret=g[xp[n*n]][yp[n*n]][n*n][i];
}
}
printf("%d %d\n",ans,ret);
return ;
}
CF1065D的更多相关文章
- CF1065D Three Pieces
题目描述:给出一个n*n的棋盘,棋盘上每个格子有一个值.你有一个子,要求将这个子从1移到n*n(去k时可以经过比k大的点). 开局时它可以作为车,马,相(国际象棋).每走一步耗费时间1.你也可以中途将 ...
- CF1065D Three Pieces (多元最短路)
题目大意:给你一个棋盘,你需要控制棋子依次经过编号为1~n的所有点,棋子的可以是车,马,象,都依照国际象棋的行棋方式,每走一步消耗1单位时间,但每次更换棋子都需要额外1单位时间,求经过所有点需要的最少 ...
随机推荐
- List与逗号分隔的字符串相互转换
如果程序员想实现某种功能,有两条路可以走.一条就是自己实现,一条就是调用别人的实现,别人的实现就是所谓的API.而且大多数情况下,好多“别人”都实现了这个功能.程序员有不得不在这其中选择.大部分情况下 ...
- __call__
object.__call__(self[, args...]) Called when the instance is “called” as a function; if this method ...
- RocketMQ RPC
(1)NameServer:在MQ集群中做的是做命名服务,更新和路由发现 broker服务: (2)Broker-Master:broker 消息主机服务器: (3)Broker-Slave:brok ...
- C++ operator(重载操作符) 【转】
转自:http://www.cnblogs.com/xiangxiaodong/archive/2012/02/12/2348144.html operator是C++的关键字,它和运算符一起使用,表 ...
- 第三节,CNN案例-mnist手写数字识别
卷积:神经网络不再是对每个像素做处理,而是对一小块区域的处理,这种做法加强了图像信息的连续性,使得神经网络看到的是一个图像,而非一个点,同时也加深了神经网络对图像的理解,卷积神经网络有一个批量过滤器, ...
- gitlab的配置
一. 管理员配置 gitlab 1. 登录 gitlab 等待 docker 容器启动完成后, 登陆 http://localhost:8080 第一次访问是让我们修改管理员密码.如下所示 初始化 g ...
- Spring @Bean注解 (基于java的容器注解)
基于java的容器注解,意思就是使用Java代码以及一些注解,就可以取代spring 的 xml配置文件. 1-@Configuration & @Bean的配合 @Configuration ...
- c++从文件路径获取目录
场景 c++从文件路径获取目录 实现代码 初始化是不正确的,因为需要转义反斜杠: string filename = "C:\\MyDirectory\\MyFile.bat"; ...
- linux 用户空间获得纳秒级时间ns【转】
转自:https://www.cnblogs.com/kekukele/p/3662816.html 一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下l ...
- 解决ubuntu的gedit编辑器中文乱码的问题
hello,本人 sky 又和大家见面了很多人在使用ubuntu系统时发现打开windows系统下面写的文档的话会发现乱码,是因为编码格式的问题windows系统下面是用GB2312等编码格式进行中文 ...