zoukankan      html  css  js  c++  java
  • 问题 B: [NOIP-P1125]飙车

    题目描述

    已知公路总长L米,一共有K个赛道,你的赛车总是和公路上其他的普通的车走相反的方向,并且所有的车每秒沿赛道行驶1m(具体看图)(宇宙新秀:我的Evo IV怎么这么烂….).

    问题是:跑到终点最少撞多少次车?

    我们简化一下模型,画一个(L+1)*K的网格,设所有的车都是点,并且每秒末都会出现在这个网格的某个顶点上.公路上其他的车都以固定的1m/s的速度自上而下行驶,而你的跑车自下而上行驶,并且每秒可以从一个点行驶到它上方左上方右上方的点(假设飘移不浪费时间,具体请看图).

    我们假设,撞车不会使车损坏,不会使车减速(宇宙新秀:我的Evo IV怎么这么强~~)

    对于撞车的设定:当每秒末你的车和另外一辆车处在同一点上时,算撞车;你的车和另一辆车迎面开过来,算撞车.具体请看下图:

    假设一开始你可以选择任意一个赛道开始比赛,要求你写一个程序,计算到达终点至少要撞多少次车。

    对于上边的例子,只要开始选择第三赛道开始跑,然后一路向北,就可以不撞车而到达终点。

    输入

    首行两个数,L,K,表示赛道距离,以及有几个赛道.

    接下来L行,每行K个字符,第i行第j个字符表示公路距终点距离为i-1的第j个赛道的初始状态:0表示该点没有车,1表示该点有车.

    铭记一点:初始时你的车在第L+1行,你可以指定一个第L+1行的位置为你的车的初始位置,而第L+1行是不在输入文件里的.

    输出

    一个数ans,表示最少撞车次数

    样例输入

    6  4
    1111
    1111
    1111
    0000
    1111
    0000
    

    样例输出

    3

    提示

    初始 第一秒 第二秒 第三秒

    距终点0m  1111

    距终点1m  1111 1111

    距终点2m  1111 1111 1111

    距终点3m  0000 1111 1111 1P11

    距终点4m  1111 0000 P111 1111

    距终点5m  0000 P111 0000 1111

    距终点6m  C

    C代表该点只有你的车,P代表该点既有你的车又有其他的车.最优方案为第一秒直走,与一辆车相撞,第二秒直走,又与一辆车相撞,第三秒斜向右走,又与一辆车相撞,总共三次.如果第三秒直走,将与两辆车相撞,那么就撞了四次,所以三次最优.

    1<=n<=100,1<=k<=10,此题中出现的所有数字均为整数

    代码

    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #include<bits/stdc++.h>
    #define rep(i,j,k) for(register int i=(j);i<=(k);++i)
    #define per(i,j,k) for(register int i=(j);i>=(k);--i)
    using namespace std;
    template<class T> inline void read(T &x)
    {
        x=0;
        register char c=getchar();
        register bool f=0;
        while(!isdigit(c))f^=c=='-',c=getchar();
        while(isdigit(c))x=x*10+c-'0',c=getchar();
        if(f)x=-x;
    }
    const int N=101;
    const int K=11;
    int f[N][K],a[N][K],n,k,ans=2147483647;
    char s;
    int main()
    {
          
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cin>>n>>k;
        per(i,n,1)
            rep(j,1,k)
            {
                cin>>s;
                a[i][j]=s-48;
                f[i][j]=0x3f3f3f3f;
            }
        for(register int i=2;i<=n;i+=2)
            rep(j,1,k)
            {
                f[i][j]=min(f[i][j],f[i-2][j]+a[i][j]+a[i-1][j]);
                if(j<k) f[i][j]=min(f[i][j],f[i-2][j+1]+a[i][j]);
                if(j>1) f[i][j]=min(f[i][j],f[i-2][j-1]+a[i][j]);
            }
        rep(i,1,k)
            ans=min(ans,f[n][i]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    图片放大镜
    带左右箭头切换的自动滚动图片JS特效
    jquery网站左侧弹出导航菜单
    网页滚动到底部自动加载
    php访问方法外变量
    图片上传预览
    GET方式,获取服务器文件
    php 邮件发送代码-php邮件群发
    java正则
    sql之left join、right join、inner join的区别
  • 原文地址:https://www.cnblogs.com/LJA001162/p/12725004.html
Copyright © 2011-2022 走看看