zoukankan      html  css  js  c++  java
  • Help Jimmy POJ

    题意:中文 https://vjudge.net/problem/POJ-1661

    题解:设两个dp数组,dpl[i]存 从第i块板左边到地上所花的最短时间,dpr[i]存右边的。

        将所有板按高度排序 ,从地面到人分别编号为0,1~n, n+1

    坑:dp方程写错了个字母。

      一开始只用了一个dp数组(还改半天)

      没考虑同一高度

      人与地板算入dp数组时的赋值

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<set>
    #include<algorithm>
    #include<stack>
    #include<string>
    #include<cstdio>
    #define _for(i, a, b) for (int i = (a); i<(b); ++i)
    using namespace std;
    const int N = 1e3 + 5;
    
    struct plat {
        int l, r, h;
    }p[N];
    int dpl[N],dpr[N];//从第e块plat边缘一直掉到地上所需的最短时间
    bool cmp(plat a, plat b) {
        return a.h < b.h;
    }
    int find(int x,int now) {
        if (now == 0) return 0;
        else for (int i = now-1; i >=0; i--) {
            if (p[i].h == p[now].h)continue;//改:同高度//其实不用考虑
            if (p[i].l <= x&&p[i].r >= x) return i;
        }
        return 0;//直接掉到地上
    }
    //大改:算法错误。
    int main()                                  
    {
        int t;
        cin >> t;
        while (t--) {
            _for(i, 0, N) dpl[i]=dpr[i] = 1e9;
            int n, x, y, mn;
            cin >> n >> x >> y >> mn;
            _for(i, 1, n+1) {cin >>p[i].l>>p[i].r>>p[i].h;}
            p[n+1].l = p[n+1].r = x; p[n+1].h = y;
            p[0].l = -2e6; p[0].r = 2e6; p[0].h = 0; //改:考虑掉到地上,不能这样改。
            sort(p, p + n+2,cmp);
            //查找落到下面的那一块:可以排序后二分
            _for(i, 1, n+1) {
                int idl= find(p[i].l,i), idr= find(p[i].r,i);
                if (idl == 0) { if (p[i].h <= mn) dpl[i] = p[i].h; }
                else if (p[i].h - p[idl].h <= mn) 
            { dpl[i] = min(dpl[i], dpl[idl] + p[i].h - p[idl].h + p[i].l - p[idl].l);
            dpl[i] = min(dpl[i], dpr[idl] + p[i].h - p[idl].h - p[i].l + p[idl].r);} if (idr == 0) { if (p[i].h <= mn) dpr[i] = p[i].h; } else if (p[i].h - p[idr].h <= mn) { dpr[i] = min(dpr[i], dpl[idr] + p[i].h - p[idr].h + p[i].r - p[idr].l); dpr[i] = min(dpr[i], dpr[idr] + p[i].h - p[idr].h - p[i].r + p[idr].r); } } int i = n + 1; int idl = find(p[i].l, i); if (idl == 0) { if (p[i].h - p[idl].h <= mn) dpl[i] = p[i].h - p[idl].h; } else if (p[i].h - p[idl].h <= mn) { dpl[i] = min(dpl[i], dpl[idl] + p[i].h - p[idl].h + p[i].l - p[idl].l); dpl[i] = min(dpl[i], dpr[idl] + p[i].h - p[idl].h - p[i].l + p[idl].r); } cout << dpl[n+1]<<endl; } system("pause"); }

     附记忆递归代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<set>
    #include<algorithm>
    #include<stack>
    #include<string>
    #include<cstdio>
    #define _for(i, a, b) for (int i = (a); i<(b); ++i)
    using namespace std;
    const int N = 1e3 + 5;
    const int INF = 1e6;
    struct plat {
        int l, r, h;
        bool operator<(const plat &p2)const { return h > p2.h; }
    }p[N];
    int dpl[N],dpr[N],L[N];//从第e块plat边缘一直掉到地上所需的最短时间
    bool cmp(plat a, plat b) {
        return a.h < b.h;
    }
    int find(int x,int now) {
        if (now == 0) return 0;
        else for (int i = now-1; i >=0; i--) {
            if (p[i].h == p[now].h)continue;//改:同高度
            if (p[i].l <= x&&p[i].r >= x) return i;
        }
        return 0;//直接掉到地上
    }
    int n, x, y, mn;
    int dpfun(int l, bool bleft) {
        int y = p[l].h, x;
        x = bleft ? p[l].l : p[l].r;
        int i;
        for ( i = l+1; i <= n; i++) if (p[i].l <= x&&p[i].r >= x) { break; }
            
            if (i <= n) { if (y - p[i].h >mn)  return INF;  }else {if(y>mn)return INF;else return y;}
            int nl = y - p[i].h + x - p[i].l;
            int nr = y - p[i].h + p[i].r - x;
            if (dpl[i] == -1)dpl[i] = dpfun(i, true);
            if (L[i] == -1)L[i] = dpfun(i, false);
            nl += dpl[i];
            nr += L[i];
            if (nl < nr)return nl; return nr;
    
    
        
    
    }
    //大改:算法错误。
    int main()                                  
    {
        int t;
        cin >> t;
        while (t--) {
            _for(i, 0, N) dpl[i] = dpr[i] =L[i]= -1;
    
            cin >> n >> x >> y >> mn;
            _for(i, 1, n + 1) { cin >> p[i].l >> p[i].r >> p[i].h; }
    
            p[0].l = x; p[0].r = x; p[0].h = y; //改:考虑掉到地上,不能这样改。
            sort(p, p + n + 1);
            //查找落到下面的那一块:可以排序后二分
            cout << dpfun(0, true) << endl;
        }
        system("pause");
    } 
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    UVALive 7509 Dome and Steles
    HDU 5884 Sort
    Gym 101194H Great Cells
    HDU 5451 Best Solver
    HDU 5883 The Best Path
    HDU 5875 Function
    卡特兰数
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    Spark Scala Flink版本对应关系
  • 原文地址:https://www.cnblogs.com/SuuT/p/8728629.html
Copyright © 2011-2022 走看看