• POJ 1661 Help Jimmy


    简单DP,每一条线段记录两个值,到左端点最少时间与到又端点最少时间。按照这个往后推导。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<string>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1000+10;
    int T;
    int N,X,Y,MAX;
    struct W
    {
        int x1,x2,h;
    } s[maxn];
    int dpLeft[maxn],dpRight[maxn];
    
    bool cmp(const W&a,const W&b)
    {
        return a.h>b.h;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d",&N,&X,&Y,&MAX);
            s[0].x1=X,s[0].x2=X,s[0].h=Y;
            for(int i=1; i<=N; i++) scanf("%d%d%d",&s[i].x1,&s[i].x2,&s[i].h);
            s[N+1].x1=-0x7fffffff,s[N+1].x2=0x7FFFFFFF,s[N+1].h=0;
    
            for(int i=0; i<=N+1; i++) dpRight[i]=dpLeft[i]=0x7fffffff;
            sort(s+1,s+N+1,cmp);
    
            dpLeft[0]=0,dpRight[0]=0;
            int ans=0x7FFFFFFF;
            for(int i=0; i<=N; i++)
            {
                //从左端下落
                if(dpLeft[i]!=0x7fffffff)
                {
                    for(int j=i+1; j<=N+1; j++)
                    {
                        if(s[j].x1<=s[i].x1&&s[i].x1<=s[j].x2)
                        {
                            if(s[i].h-s[j].h<=MAX)
                            {
                                if(j==N+1)
                                {
                                    int cost=dpLeft[i]+s[i].h-s[j].h;
                                    ans=min(ans,cost);
                                }
                                else
                                {
                                    int cost;
                                    //到左端需要的时间
                                    cost=dpLeft[i]+s[i].h-s[j].h+s[i].x1-s[j].x1;
                                    dpLeft[j]=min(cost,dpLeft[j]);
    
                                    //到右端需要的时间
                                    cost=dpLeft[i]+s[i].h-s[j].h+s[j].x2-s[i].x1;
                                    dpRight[j]=min(cost,dpRight[j]);
                                }
                            }
                            break;
                        }
                    }
                }
                //往右跑
                if(dpRight[i]!=0x7fffffff)
                {
                    for(int j=i+1; j<=N+1; j++)
                    {
                        if(s[j].x1<=s[i].x2&&s[i].x2<=s[j].x2)
                        {
                            if(s[i].h-s[j].h<=MAX)
                            {
                                if(j==N+1)
                                {
                                    int cost=dpRight[i]+s[i].h-s[j].h;
                                    ans=min(ans,cost);
                                }
                                else
                                {
                                    int cost;
                                    //到左端需要的时间
                                    cost=dpRight[i]+s[i].h-s[j].h+s[i].x2-s[j].x1;
                                    dpLeft[j]=min(cost,dpLeft[j]);
    
                                    //到右端需要的时间
                                    cost=dpRight[i]+s[i].h-s[j].h+s[j].x2-s[i].x2;
                                    dpRight[j]=min(cost,dpRight[j]);
                                }
                            }
                            break;
                        }
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    GreenPlum 大数据平台--运维(二)
    GreenPlum 大数据平台--运维(一)
    GreenPlum 大数据平台--非并行备份(六)
    zabbix--高级篇-监控docker服务(一)
    GreenPlum 大数据平台--备份-邮件配置-gpcrondump & gpdbrestore(五)
    subprocess模块
    Python写随机发红包的原理流程
    粘包
    网络编程: 基于UDP协议的socket
    网络编程: 基于TCP协议的socket, 实现一对一, 一对多通信
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5144013.html
Copyright © 2020-2023  润新知