【dp动态规划】飙车
2016-06-01 23:34
232 查看
【问题描述】
[说明]此题中出现的所有数字均为整数 [背景]有天SubRaY发现宇宙新秀在玩一个游戏叫Need For Speed(什么?连大名鼎鼎的极品飞车都没听说过..),他发现宇宙新秀总是逆行,于是出现以下对话: SubRaY:你怎么老是在逆行道跑.. 宇宙新秀:近! SubRaY:你就不怕撞车.. 宇宙新秀:你提前写个程序计算一下不就完了! SubRaY:…… SubRaY实在不会写这个程序,于是他交给你.. [题目描述]已知公路总长L米,一共有K个赛道,你的赛车总是和公路上其他的普通的车走相反的方向,并且所有的车每秒沿赛道行驶1m(具体看图)(宇宙新秀:我的Evo IV怎么这么烂….). 问题是:跑到终点最少撞多少次车? 我们简化一下模型,画一个(L+1)*K的网格,设所有的车都是点,并且每秒末都会出现在这个网格的某个顶点上.公路上其他的车都以固定的1m/s的速度自上而下行驶,而你的跑车自下而上行驶,并且每秒可以从一个点行驶到它上方\左上方\右上方的点(假设飘移不浪费时间,具体请看图). 我们假设,撞车不会使车损坏,不会使车减速(宇宙新秀:我的Evo IV怎么这么强~~) 对于撞车的设定:当每秒末你的车和另外一辆车处在同一点上时,算撞车;你的车和另一辆车迎面开过来,算撞车.具体请看下图:
假设一开始你可以选择任意一个赛道开始比赛,要求你写一个程序,计算到达终点至少要撞多少次车. 对于上边的例子,只要开始选择第三赛道开始跑,然后一路向北,就可以不撞车而到达终点
【问题分析】
很基础的动归题,用F[i][j]表示当车子行驶到第i行第j列时能获得的最少碰撞次数,那么因为已知有三种走法,故可以写出方程式
F[i][j]=min(F[i-2][j]+c[i-1][j],min(F[i-2][j-1],F[i-2][j+1]))+c[i][j]
因为如果你是漂移的话,在漂移过程中是不会受到碰撞,根据运动的相对性,我们可以把赛车的速度设为2,然后假设其他车辆全都不许动!(我们都是木头人,祝oier们6.1快乐),再加上一些判定是否超出边境的情况即可。
我真是业界良心啊 。。。 希望能对将来在OI里沉浮的学弟学妹们有所帮助。
[说明]此题中出现的所有数字均为整数 [背景]有天SubRaY发现宇宙新秀在玩一个游戏叫Need For Speed(什么?连大名鼎鼎的极品飞车都没听说过..),他发现宇宙新秀总是逆行,于是出现以下对话: SubRaY:你怎么老是在逆行道跑.. 宇宙新秀:近! SubRaY:你就不怕撞车.. 宇宙新秀:你提前写个程序计算一下不就完了! SubRaY:…… SubRaY实在不会写这个程序,于是他交给你.. [题目描述]已知公路总长L米,一共有K个赛道,你的赛车总是和公路上其他的普通的车走相反的方向,并且所有的车每秒沿赛道行驶1m(具体看图)(宇宙新秀:我的Evo IV怎么这么烂….). 问题是:跑到终点最少撞多少次车? 我们简化一下模型,画一个(L+1)*K的网格,设所有的车都是点,并且每秒末都会出现在这个网格的某个顶点上.公路上其他的车都以固定的1m/s的速度自上而下行驶,而你的跑车自下而上行驶,并且每秒可以从一个点行驶到它上方\左上方\右上方的点(假设飘移不浪费时间,具体请看图). 我们假设,撞车不会使车损坏,不会使车减速(宇宙新秀:我的Evo IV怎么这么强~~) 对于撞车的设定:当每秒末你的车和另外一辆车处在同一点上时,算撞车;你的车和另一辆车迎面开过来,算撞车.具体请看下图:
假设一开始你可以选择任意一个赛道开始比赛,要求你写一个程序,计算到达终点至少要撞多少次车. 对于上边的例子,只要开始选择第三赛道开始跑,然后一路向北,就可以不撞车而到达终点
【问题分析】
很基础的动归题,用F[i][j]表示当车子行驶到第i行第j列时能获得的最少碰撞次数,那么因为已知有三种走法,故可以写出方程式
F[i][j]=min(F[i-2][j]+c[i-1][j],min(F[i-2][j-1],F[i-2][j+1]))+c[i][j]
因为如果你是漂移的话,在漂移过程中是不会受到碰撞,根据运动的相对性,我们可以把赛车的速度设为2,然后假设其他车辆全都不许动!(我们都是木头人,祝oier们6.1快乐),再加上一些判定是否超出边境的情况即可。
我真是业界良心啊 。。。 希望能对将来在OI里沉浮的学弟学妹们有所帮助。
#include <iostream> #include <cstdio> #include <climits> using namespace std; const int N=101; const int K=11; const int inf=INT_MAX; int n,k,ans; bool c [K]; int F [K]; void read() { int i,j; char temp; scanf("%d%d",&n,&k); getchar(); for (i=n;i>=1;i--) { for (j=1;j<=k;j++) { temp=getchar(); if (temp=='1') c[i][j]=1; } getchar(); } if (n%2==1) n--; for (i=1;i<=n;i++) for (j=1;j<=k;j++) F[i][j]=inf; ans=inf; return; } void dp() { int i,j,l; bool flag; for (i=2;i<=n;i+=2) for (j=1;j<=k;j++) { flag=0; if (c[i][j]) flag=1; if (j>1) F[i][j]=min(F[i][j],F[i-2][j-1]+flag); if (j<k) F[i][j]=min(F[i][j],F[i-2][j+1]+flag); F[i][j]=min(F[i][j],F[i-2][j]+c[i-1][j]+flag); } for (i=1;i<=k;i++) ans=min(ans,F [i]); printf("%d\n",ans); return; } int main() { freopen("nfs.in","r",stdin); freopen("nfs.out","w",stdout); read(); dp(); return 0; }
相关文章推荐
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- 动态规划
- Android dpi,dip,dp的概念以及屏幕适配
- C++ 动态规划
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- 动态规划解决背包问题的核心思路
- DP(动态规划) 解游轮费用问题
- Android对px和dip进行尺寸转换的方法
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门