这个题目我昨晚看到的,没什么思路,因为马里奥有boot加速器,只要中间没有城堡,即可不耗时间和脚力,瞬间移动不超过L距离,遇见城堡就要停下来,当然不能该使用超过K次。。。我纠结了很久,最终觉得还是只能写个BFS,剪了下枝,不出意料还是TLE。。。

后来还是找的别人博客看了一下。。。其实之前也做了好多DP,也应该能想到,既然加速器可以用k次,则,每个点都有k个状态,通过DP,把各个状态进行下取优,就可以了。。。

这不得不让我对DP有了些新的理解,DP在状态转移的时候,就好像最短路里面的松弛操作,或者二者只是外表的不同,本质是遵循一个道理。

当然在DP之前还需要一些处理

首先用个g[][]二维数组把题目所给的路径给存下来,再用Floyd把点到点的最短路先求出来,当然不是完全的Floyd,因为这个floyd求出来的最短路完全是为了之后用加速器,加速器不允许途中有城堡,因此在floyd的时候要加判断条件,有城堡在中间就不走。

用一个d[i][k]表示i点在加速器使用了k次的最短路径。

一开始还以为是总加速距离不能超过L,后来发现原来是每次。要细心

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 110
#define INF 1<<29
using namespace std;
int A,B,M,L,K;
int g[N][N],d[N][];
int q[N*],st[N*],inq[N][];
void init()
{
for (int i=;i<=A+B;i++)
{
for (int j=;j<=A+B;j++)
{
if (i==j){
g[i][j]=;
}
else
g[i][j]=INF;
}
}
}
void floyd()
{
int i,j,k;
for (k=;k<=A+B;k++)
{
for (i=;i<=A+B;i++)
{
for (j=;j<=A+B;j++)
{
if (k>A) continue;//Floyd 只求能用加速器飞越的最短路
if (g[i][j]>g[i][k]+g[k][j])
g[i][j]=g[i][k]+g[k][j];
//cout<<g[i][j]<<" "<<i<<" "<<j<<endl;
}
}
}
}
void solve()
{
int maxn=(K+)*(A+B);
int front=,rear=;
memset(inq,,sizeof inq);
for (int i=;i<=A+B;i++)
{
for (int j=;j<=K;j++)
{
d[i][j]=INF;
//cout<<d[i][j]<<endl;
}
}
d[A+B][]=; //初始状态
q[rear]=A+B; //这次尝试了一下手动队列,而不是STL队列,效果相同,不过手工的队列时间应该好一些。
st[rear]=;
rear++;
while (front!=rear)
{
int u=q[front];
int k=st[front];
front++;
if (front>maxn)
front=;
inq[u][k]=;
// cout<<u<<" "<<k<<" "<<d[u][k]<<endl;
for (int i=;i<=A+B;i++)
{
if (d[i][k]>d[u][k]+g[u][i]) //进行普通最短路,保存当前状态
{
d[i][k]=d[u][k]+g[u][i];
if (!inq[i][k])
{
q[rear]=i;
st[rear]=k;
rear++;
if (rear>maxn)
rear=;
inq[i][k]=;
}
}
if (g[u][i]<=L && k<K && d[u][k]<d[i][k+]) //如果能够进行加速,并且加速后能更新加速后的状态,则加速,并且保存该状态。
{
d[i][k+]=d[u][k];
if (!inq[i][k+])
{
inq[i][k+]=;
q[rear]=i;
st[rear]=k+;
rear++;
if (rear>maxn)
rear=;
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{ scanf("%d%d%d%d%d",&A,&B,&M,&L,&K);
init();
for (int i=;i<=M;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=c;
}
floyd();
solve();
int ans=INF;
for (int i=;i<=K;i++)
if (ans>d[][i])
ans=d[][i];
printf("%d\n",ans);
}
return ;
}

其实整个动规过程就是最短路的松弛过程,尤其是它把每个点的状态都求到了,并且把松弛成功(或者说状态转移成功)的点又存贮进了队列,以它来继续寻求更新其他点,这种思想应该可以再用到以后其他的DP问题中

UVA 10269 Super Mario,最短路+动态规划的更多相关文章

  1. zoj1232Adventure of Super Mario(图上dp)

    题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...

  2. UVA10269 Adventure of Super Mario(Floyd+DP)

    UVA10269 Adventure of Super Mario(Floyd+DP) After rescuing the beautiful princess, Super Mario needs ...

  3. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  4. Teaching Your Computer To Play Super Mario Bros. – A Fork of the Google DeepMind Atari Machine Learning Project

    Teaching Your Computer To Play Super Mario Bros. – A Fork of the Google DeepMind Atari Machine Learn ...

  5. hdu4177:Super Mario

    主席树+离散化.给一段区间.多次询问[l,r]中有多少个数小于k.啊主席树用指针版写出来优美多了QAQ... #include<cstdio> #include<cstring> ...

  6. 主席树:HDU 4417 Super Mario

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. hdu4417 Super Mario 树阵离线/划分树

    http://acm.hdu.edu.cn/showproblem.php?pid=4417 Super Mario Time Limit: 2000/1000 MS (Java/Others)    ...

  8. Super Mario

    Super Mario Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  9. UVA - 12298 Super Poker II NTT

    UVA - 12298 Super Poker II NTT 链接 Vjudge 思路 暴力开个桶,然后统计,不过会T,用ntt或者fft,ntt用个大模数就行了,百度搜索"NTT大模数&q ...

随机推荐

  1. SQL语句对MySQL数据库的操作之对数据库层面的操作

    一.数据库内部存储结构 字段->数据表->数据库->MySQL服务器 二.登录及退出数据库 mysql -h服务器地址 -u用户名 -p密码(这样的登录形式并不安全) mysql - ...

  2. Thread start0 启动分析 一图看懂

    参考文章: https://segmentfault.com/a/1190000017255007 https://segmentfault.com/a/1190000020194154 1.线程启动 ...

  3. Lombok认知

    Lombok的简介 Lombok是一款Java开发插件,公司项目到处使用,整体效果很棒,代码更干净.Java开发人员可以节省出重复构建,诸如hashCode和equals这样的方法以及各种业务对象模型 ...

  4. Vue.js(23)之 keepAlive和activated

    阅读: vue中前进刷新.后退缓存用户浏览数据和浏览位置的实践 keep-alive 组件级缓存 keep-alive <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而 ...

  5. 图床工具PicGO实现七牛云图片上传

    图床工具PicGO实现七牛云图片上传 我们在写博客或者网络文章时经常需要上传图片.目前最有名气的图床工具就是PicGO. 简单的界面,完整的功能,在相册里也能直接复制markdown图片链接.一直深受 ...

  6. 面向对象-接口(interface)实战案例

    面向对象-接口(interface)实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.接口(interface)概述 1>.接口的语法格式 接口时抽象类的一种特殊体 ...

  7. C++基础--引用的一点补充

    这一篇是对引用的一点补充,内容基本上是来自<C++ primer plus>一书第八章的内容. 前面一篇介绍了引用的一点特点,这里补充一个,将引用用于类对象的时候,有一个体现继承的特征,就 ...

  8. Python属性和内建属性

    属性property 1. 私有属性添加getter和setter方法 class Money(object): def __init__(self): self.__money = 0 def ge ...

  9. stm32f4 dma + uart idle + double 调试小记

    使用 stm32f4 调试uart 接收, 使用 空闲中断,dma 双缓冲模式,有以下几点需要注意的. 调试的时候断点不要打在 if (USART_GetITStatus(USART6, USART_ ...

  10. 吴裕雄--天生自然TensorFlow2教程:测试(张量)- 实战

    import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets import os ...