Help Jimmy POJ - 1661 dp

#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;
}

 

posted @ 2020-01-28 18:27  晴屿  阅读(231)  评论(0编辑  收藏  举报