• Help Jimmy POJ


    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=1010;
    const int M=20010;
    const int INF=0x3f3f3f;
    struct Time
    {
        int x1,x2,h;
    }a[N];
    int dp[N+2][2]; // 0:表示第i的木板左边到底部的最短时间
                  // 1: 表示第i的木板右边到底部的最短时间
    int n,x,y,max_h;
    int cmp(Time c,Time b) //排序函数
    {
        return c.h > b.h; //从大到小排列
    }
    void left(int i)//
    {
        //如果平台i下面有平台,且两者相距不超过MAX
        int k = i+1;
        while( k<n+1 && a[i].h-a[k].h<=max_h ) //n+1处是地面
        {
            //确保平台k在平台i的左下方,且小鼠可以跳到上面
            if(a[i].x1>=a[k].x1&&a[i].x1<= a[k].x2)
            {
                //从i的左端跳到地面的时间
                //i先跳到k的时间+
                //min(从k左端跳到地面的时间+从i的左端到k的左端的时间,从k的右端跳到地面的时间+从i左端到k的右端) 
                dp[i][0]=a[i].h-a[k].h+min(dp[k][0]+a[i].x1-a[k].x1,dp[k][1]+a[k].x2-a[i].x1);
                return;
            }
            k++;
        }
        //因为第二个条件出的循环即:不能到达下一平台
        if(a[i].h-a[k].h>max_h)
            dp[i][0]=INF;
        //因为它下面没木板,直接落地
        else
            dp[i][0]=a[i].h; 
    }
    void right(int i)//
    {
        //如果平台i下面有平台,且两者相距不超过MAX
        int k=i+1;
        while(k<n+1 && a[i].h-a[k].h<=max_h)
        {
            //确保平台k在平台i的右下方,且小鼠可以跳到上面
            if(a[i].x2<=a[k].x2 && a[i].x2 >= a[k].x1)
            {
                dp[i][1]=a[i].h-a[k].h+min(dp[k][0] + a[i].x2-a[k].x1  ,  dp[k][1] + a[k].x2-a[i].x2);
                return;
            }
            k++;
        }
        //不能到达下一平台
        if(a[i].h-a[k].h > max_h)
            dp[i][1]=INF;
        //因为它下面没木板,直接落地
        else
            dp[i][1]=a[i].h;
    }
    int main()
    {
        int t,i;
        cin>>t;
        while(t--)
        {
            //木板个数、老鼠的初始坐标、最大跳跃高度
            cin>>n>>x>>y>>max_h;
            //地面也当做一块木板
            a[0].x1=-20000;
            a[0].x2=20000;
            a[0].h=0;
            //老鼠初始位置也当做一块木板
            a[1].x1=x;
            a[1].x2=x;
            a[1].h=y;
            //输入数据
            for(i=2;i<=n+1;i++)
                cin>>a[i].x1>>a[i].x2>>a[i].h;
            //高度从大到小
            sort(a,a+n+2,cmp);
            //初始化
            memset(dp,0,sizeof(dp)); 
            //n+1是地面 
            //所以从n开始 
            for(i=n; i>=0 ;i--)
            {
                //进行左:去bfs
                left(i);
                //进行右:去bfs
                right(i);
            }
            cout<<min(dp[0][0],dp[0][1])<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Linux账户密码安全策略设置 /etc/login.defs:
    GPS网络时间服务器安装注意事项
    ntp时间校准服务器的调试方法
    北斗网络时钟服务器的特点
    sntp时间服务器的介绍
    网络校时服务器
    综合时间码分配器介绍
    子母钟系统介绍
    智能计数器简介
    怎样选择通用计数器?
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12238564.html
Copyright © 2020-2023  润新知