【问题描述】

  FJ建造了一个美丽的池塘,用于让奶牛们锻炼。这个长方形的池子被分割成了 M 行和 N 列(正方形格子的 。某些格子上有莲花,还有一些岩石,其余的只是美丽,纯净,湛蓝的水。
  贝茜正在练习芭蕾舞,她从一个莲花跳跃到另一个莲花,当前位于一个莲花。她希望在莲花上一个一个的跳,目标是另一个给定莲花。她不能跳入水中,也不能跳到岩石上。贝茜的每次的跳跃像国际象棋中的骑士一样:横向移动1,纵向移动2,或纵向移动1,横向移动2。所以贝茜有时可能会有多达8个选择的跳跃。
  FJ在观察贝茜的芭蕾舞,他意识到有时候贝茜有可能跳不到她想去的目的地,因为路上有些地方没有莲花。于是他想要添加几个莲花使贝茜能够完成任务。一贯节俭的FJ想添加最少数量的莲花。当然,莲花不能放在石头上。
  请帮助FJ确定必须要添加的莲花的最少数量。在添加的莲花最少基础上,算出贝茜从起始点跳到目标点需要的最少的步数。最后,还要算出满足添加的莲花的最少数量时,跳跃最少步数的跳跃路径的条数。

【输入格式】

  第1行: 两个整数M,N。
  第2..M+1 行:第i+1行,第i+1行有N个整数,表示该位置的状态: 0为水; 1为莲花; 2为岩石; 3为贝茜开始的位置; 4为贝茜要去的目标位置.

【输出格式】

  第1行: 一个整数: 需要添加的最少的莲花数. 如果无论如何贝茜也无法跳到,输出-1。
  第2行: 一个整数:在添加的莲花最少基础上,贝茜从起始点跳到目标点需要的最少的步数。如果第1行输出-1,这行不输出。
  第3行: 一个整数: 添加的莲花的最少数量时,跳跃步数为第2行输出的值的跳跃路径的条数 如果第1行输出-1,这行不输出。

【输入样例】

4 8
0 0 0 1 0 0 0 0
0 0 0 0 0 2 0 1
0 0 0 0 0 4 0 0
3 0 0 0 0 0 1 0

【输出样例】

2
6
2

【样例解释】

至少要添加2朵莲花,放在了’x’的位置。
0 0 0 1 0 0 0 0    0 0 0 1 0 0 0 0
0 x 0 0 0 2 0 1    0 0 0 0 0 2 0 1
0 0 0 0 x 4 0 0    0 0 x 0 x 4 0 0
3 0 0 0 0 0 1 0    3 0 0 0 0 0 1 0
贝茜至少要跳6步,有以下两种方案
0 0 0 C 0 0 0 0    0 0 0 C 0 0 0 0
0 B 0 0 0 2 0 F    0 0 0 0 0 2 0 F
0 0 0 0 D G 0 0    0 0 B 0 D G 0 0
A 0 0 0 0 0 E 0    A 0 0 0 0 0 E 0

【数据范围】

1 ≤ M ≤ 30
1 ≤ N ≤ 30

分析:乍一看就是棋盘上的最短路问题,但是可以给他“铺路”就加大了难度,加上问题要求输出最小的铺路代价,最小代价下的最小的步数,最小步数下的路径条数,这道题还是有一定难度的。

1.先把最优情况下的方案数搁在一边,看看怎么求最小距离(步数)。
既然是隐式图的模型,那么肯定要用Dijkstra/SPFA求解啦。那么写着写着问题就来了,如何让最小的铺路代价优先于步数呢?一开始想设置状态数组dist[i][j][g]表示从起点走到(i,j),铺路代价为g的最少步数,但是发现无法保证代价优先,而且思路很混乱。
因为每个格子有两个需要求的最优值,明智的选择就是开两个数组dist[i][j]->最少步数,cost[i][j]->最小代价,每从节点(x,y)搜索到一个新的点(tx,ty)的时候松弛操作的思路如下:

  1. if(cost[x][y]+cost((x,y)->(tx,ty)) 小于 cost[tx][ty])那么不论步数如何,都应该从(x,y)走到(tx,ty)。
  2. if(cost[x][y]+cost((x,y)->(tx,ty))==cost[tx][ty]) 那么还要判断步数是否更少 if(dist[x][y]+1 小于 dist[tx][ty]) 才从(x,y)走到(tx,ty)

那么算完之后的dist[ex][ey],cost[ex][ey]就是最小步数和最小代价了

2.如何计算最优路径条数呢?
第一种想法是把在最优路径上的边连成一张DAG图,再在图上进行BFS+动态规划,但是这里已经写了这么长一段代码了能不能好好利用一下呢?
我们发现算最优路的松弛操作时,不就可以顺带把方案数求出来了吗。我们设f[i][j]表示从起点到(i,j)的最优路径条数,思路如下:

  1. 如果从(x,y)->(tx,ty)更优,那么f[tx][ty]=f[x][y];
  2. 如果从(x,y)->(tx,ty)一样优秀,那么f[tx][ty]+=f[x][y];

这两个步骤可以合在一段最短路的代码里面,然后输出就可以了。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=35;
const int inf=16843009;
int w[maxn][maxn],dist[maxn][maxn],inq[maxn][maxn],cost[maxn][maxn],n,m,sx,sy,ex,ey;
LL f[maxn][maxn];
int dx[]={-1,-2,-2,-1,1,2,2,1},dy[]={2,1,-1,-2,-2,-1,1,2};
struct data
{int x,y;
};
void SPFA()
{queue<data>q;q.push((data){sx,sy});memset(dist,1,sizeof(dist));memset(cost,1,sizeof(cost));dist[sx][sy]=0;cost[sx][sy]=0;inq[sx][sy]=1;f[sx][sy]=1;data t,tt;int ww;while(!q.empty()){t=q.front();q.pop();if(t.x==ex && t.y==ey){continue;} inq[t.x][t.y]=0;for(int x=0;x<8;x++){ww=0;tt=(data){t.x+dx[x],t.y+dy[x]};if(tt.x<1 || tt.x>n || tt.y<1 || tt.y>m) continue;if(w[tt.x][tt.y]==2) continue;if(w[tt.x][tt.y]==0) ww=1;//松弛操作: if(cost[t.x][t.y]+ww<cost[tt.x][tt.y])//代价较小则必选(不考虑步数大小) {cost[tt.x][tt.y]=cost[t.x][t.y]+ww;dist[tt.x][tt.y]=dist[t.x][t.y]+1;f[tt.x][tt.y]=f[t.x][t.y];if(inq[tt.x][tt.y]) continue;inq[tt.x][tt.y]=1;q.push(tt); }else if(cost[t.x][t.y]+ww==cost[tt.x][tt.y])//代价相等{if(dist[t.x][t.y]+1<dist[tt.x][tt.y])//步数较小 {dist[tt.x][tt.y]=dist[t.x][t.y];f[tt.x][tt.y]=f[t.x][t.y];if(inq[tt.x][tt.y]) continue;inq[tt.x][tt.y]=1;q.push(tt);}else if(dist[t.x][t.y]+1==dist[tt.x][tt.y])//步数也相等则方案数相加{f[tt.x][tt.y]+=f[t.x][t.y];}}}}if(dist[ex][ey]==inf) {printf("-1\n");return;}printf("%d\n%d\n",cost[ex][ey],dist[ex][ey]);cout<<f[ex][ey];
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&w[i][j]);if(w[i][j]==3) sx=i,sy=j;else if(w[i][j]==4) ex=i,ey=j;}SPFA();return 0;
}

有趣的隐式图模型——USACO CONTEST FEB07 白银莲花池相关推荐

  1. 《数据结构课程实践》_02_隐式图的搜索问题_准备工作

    02_隐式图的搜索问题_准备工作 一.实验题目与要求 二.编程语言以及开发环境 三.实验思路 A*算法 四.预习小结 一.实验题目与要求 实验要求: 对九宫重排问题,建立图的启发式搜索求解方法: 用A ...

  2. 题目2:隐式图的搜索问题(A*算法解决八数码)

    数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...

  3. php 隐式路由,关于Laravel 7 的简单隐式路由模型绑定

    搜索热词 Laravel 的下一个主要发行版本 ,你可以直接在路由定义中自定义隐式路由模型绑定: Route::get('/posts/{post:slug}',function (Post $pos ...

  4. laravel 模型里自定义属性_关于Laravel 7 的简单隐式路由模型绑定

    Laravel 的下一个主要发行版本 ,你可以直接在路由定义中自定义隐式路由模型绑定: Route::get('/posts/{post:slug}', function (Post $post) { ...

  5. 《数据结构课程实践》_02_隐式图的搜索问题_实现

    02_隐式图的搜索问题_实现 一.实验题目 二.编程语言以及开发环境 三.源代码 1.main类 2.节点类 3.算法类 四.运行结果 五.实验小结 一.实验题目 实验要求: 对九宫重排问题,建立图的 ...

  6. 隐式图的搜索问题(九宫重排)——实验准备

    隐式图的搜索问题(九宫重排)--实验准备 隐式图的搜索问题(九宫重排) 实验任务 实验要求 A*算法 隐式图的搜索问题(九宫重排) 实验任务 对九宫重排问题,建立图的启发式搜索求解方法. 用A*算法求 ...

  7. 隐式图的搜索问题(九宫重排)——项目实现

    隐式图的搜索问题(九宫重排)--项目实现 隐式图的搜索问题(九宫重排)--项目实现 源代码 运行结果 隐式图的搜索问题(九宫重排)--项目实现 源代码 package SearchPath;publi ...

  8. PCL_Implicit Shape Model_隐式形状模型 ISM

    http://pointclouds.org/documentation/tutorials/implicit_shape_model.php 英文文档 本教程让我们学会implicit shape ...

  9. 2.隐式图的搜索问题

    题目2:隐式图的搜索问题 实验内容 对九宫重排问题,建立图的启发式搜索求解方法: 用A*算法求解九宫重排问题. 实验要求 3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子 ...

  10. 题目2:隐式图的搜索问题(实验准备)

    题目2:隐式图的搜索问题(实验准备) 实验内容 实验要求 编程语言的选择 项目思路 项目解析 算法选择 A*算法 实验内容 对九宫重排问题,建立图的启发式搜索求解方法: 用A*算法求解九宫重排问题. ...

最新文章

  1. 5年以上的Java程序员,千万别忽略这一点
  2. java实现具有修饰的完美圣诞树
  3. 转载--httpclient原理和应用
  4. python-常用函数模块学习-subprocess
  5. “冷潮”之后,P2P或更加适合投资
  6. 关于mybatis的@Param注解和参数
  7. 【深入浅出MyBatis系列十一】缓存源码分析
  8. Spring Security(四) —— 核心过滤器源码分析
  9. NIO(一)——缓冲区Buffer
  10. 前端 domparser未定义怎么解决_开源|wwto:小程序跨端迁移解决方案——微信转其他小程序...
  11. win7x64 连接oracle 客户端 vs 2010调试 提示“ORA-12154: TNS: 无法解析指定的连接标识符 ”
  12. OpenV$P$N服务器添加客户端
  13. 查看linux系统语言并修改
  14. axure能做剪切蒙版吗_***自动售货机能做吗
  15. 使用股指期货与ETF基金进行期现套利
  16. 如何使用python刷博客浏览量---第一种方法
  17. java 骰子_Java--摇骰子
  18. linux环境下解压压缩包失败
  19. excel查找出不来了_Excel技巧:明明看到1了,为什么查找不到?
  20. 超强的在线设计Logo工具:Logo Creator_logo_UE

热门文章

  1. Android Studio升级到3.5之后xml格式化问题
  2. edp和edt哪个好_邂逅的香水 到底是EDT 好还是 EDP 好?
  3. mac 更新系统后 idea 意外退出
  4. Linux网站服务之部署Wordpress教程
  5. 大数据发展趋势之我见
  6. SpringMVC:视图解析器(ViewResolver)
  7. 《修C传》——初始C语言 <凝气篇>
  8. SLT容器使用技巧以及注意事项
  9. logback配置信息详解
  10. 基于优化LSTM 模型的股票预测