有趣的隐式图模型——USACO CONTEST FEB07 白银莲花池
【问题描述】
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)的时候松弛操作的思路如下:
- if(cost[x][y]+cost((x,y)->(tx,ty)) 小于 cost[tx][ty])那么不论步数如何,都应该从(x,y)走到(tx,ty)。
- 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)的最优路径条数,思路如下:
- 如果从(x,y)->(tx,ty)更优,那么f[tx][ty]=f[x][y];
- 如果从(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 白银莲花池相关推荐
- 《数据结构课程实践》_02_隐式图的搜索问题_准备工作
02_隐式图的搜索问题_准备工作 一.实验题目与要求 二.编程语言以及开发环境 三.实验思路 A*算法 四.预习小结 一.实验题目与要求 实验要求: 对九宫重排问题,建立图的启发式搜索求解方法: 用A ...
- 题目2:隐式图的搜索问题(A*算法解决八数码)
数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...
- php 隐式路由,关于Laravel 7 的简单隐式路由模型绑定
搜索热词 Laravel 的下一个主要发行版本 ,你可以直接在路由定义中自定义隐式路由模型绑定: Route::get('/posts/{post:slug}',function (Post $pos ...
- laravel 模型里自定义属性_关于Laravel 7 的简单隐式路由模型绑定
Laravel 的下一个主要发行版本 ,你可以直接在路由定义中自定义隐式路由模型绑定: Route::get('/posts/{post:slug}', function (Post $post) { ...
- 《数据结构课程实践》_02_隐式图的搜索问题_实现
02_隐式图的搜索问题_实现 一.实验题目 二.编程语言以及开发环境 三.源代码 1.main类 2.节点类 3.算法类 四.运行结果 五.实验小结 一.实验题目 实验要求: 对九宫重排问题,建立图的 ...
- 隐式图的搜索问题(九宫重排)——实验准备
隐式图的搜索问题(九宫重排)--实验准备 隐式图的搜索问题(九宫重排) 实验任务 实验要求 A*算法 隐式图的搜索问题(九宫重排) 实验任务 对九宫重排问题,建立图的启发式搜索求解方法. 用A*算法求 ...
- 隐式图的搜索问题(九宫重排)——项目实现
隐式图的搜索问题(九宫重排)--项目实现 隐式图的搜索问题(九宫重排)--项目实现 源代码 运行结果 隐式图的搜索问题(九宫重排)--项目实现 源代码 package SearchPath;publi ...
- PCL_Implicit Shape Model_隐式形状模型 ISM
http://pointclouds.org/documentation/tutorials/implicit_shape_model.php 英文文档 本教程让我们学会implicit shape ...
- 2.隐式图的搜索问题
题目2:隐式图的搜索问题 实验内容 对九宫重排问题,建立图的启发式搜索求解方法: 用A*算法求解九宫重排问题. 实验要求 3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子 ...
- 题目2:隐式图的搜索问题(实验准备)
题目2:隐式图的搜索问题(实验准备) 实验内容 实验要求 编程语言的选择 项目思路 项目解析 算法选择 A*算法 实验内容 对九宫重排问题,建立图的启发式搜索求解方法: 用A*算法求解九宫重排问题. ...
最新文章
- 5年以上的Java程序员,千万别忽略这一点
- java实现具有修饰的完美圣诞树
- 转载--httpclient原理和应用
- python-常用函数模块学习-subprocess
- “冷潮”之后,P2P或更加适合投资
- 关于mybatis的@Param注解和参数
- 【深入浅出MyBatis系列十一】缓存源码分析
- Spring Security(四) —— 核心过滤器源码分析
- NIO(一)——缓冲区Buffer
- 前端 domparser未定义怎么解决_开源|wwto:小程序跨端迁移解决方案——微信转其他小程序...
- win7x64 连接oracle 客户端 vs 2010调试 提示“ORA-12154: TNS: 无法解析指定的连接标识符 ”
- OpenV$P$N服务器添加客户端
- 查看linux系统语言并修改
- axure能做剪切蒙版吗_***自动售货机能做吗
- 使用股指期货与ETF基金进行期现套利
- 如何使用python刷博客浏览量---第一种方法
- java 骰子_Java--摇骰子
- linux环境下解压压缩包失败
- excel查找出不来了_Excel技巧:明明看到1了,为什么查找不到?
- 超强的在线设计Logo工具:Logo Creator_logo_UE