POJ 1661 Help Jimmy

来源:互联网 发布:移动数据开着不能上网 编辑:程序博客网 时间:2024/06/07 11:34

其实这道题感觉就是数字三角形问题翻版。

设子问题为从当前这块板子走到地面需要的时间。

每块板子只有左右两个方向走,所以对于以每块板子为起点的子问题有两个转移方向。

每个方向能到哪个板子或是不能往下跳都是可以确定的,这个可以预处理一下。


然后从高度最低的板子以前往上更新,就求出每个子问题了。


最后算一下从起始点往下跳到的第一个板子是哪块就解决了。


别忘了直接跳到地面上的情况。。。


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn=1e3+5;const int inf=1e9+7;struct node{    int x, id;};vector<node>edg[maxn];struct dp{    int x;    int pos;}dp[maxn];int X[maxn], Y[maxn], H[maxn];struct line{    int x;    int y;    int h;    bool operator <(const line & a)const    {        return h>a.h;    }}a[maxn];int main(){    int t, i, j, x, y, m, n;    cin>>t;    while(t--)    {        scanf("%d%d%d%d", &n, &x, &y, &m);        for(i=1; i<=n; i++)        {            scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].h);        }        n++;        a[n].x=-20000, a[n].y=20000, a[n].h=0;        for(i=0; i<=n; i++)edg[i].clear();        sort(a+1, a+n+1);        node pa;        for(i=1; i<=n; i++)        {            for(j=i+1; j<=n; j++)            {                if(a[j].h-a[i].h>m)break;                if(a[i].x<=a[j].y && a[i].x>=a[j].x)                {                    pa.x=a[i].x, pa.id=i;                    edg[j].push_back(pa);                    break;                }            }            for(j=i+1; j<=n; j++)            {                if(a[j].h-a[i].h>m)break;                if(a[i].y<=a[j].y && a[i].y>=a[j].x)                {                    pa.x=a[i].y, pa.id=i;                    edg[j].push_back(pa);                    break;                }            }            dp[i].x=inf;            dp[i].pos=-1;        }        for(i=1; i<=n; i++)        {            if(a[i].h-y>m)break;            if(a[i].x<=x && a[i].y>=x)            {                break;            }        }        dp[i].pos=x, dp[i].x=0;        int id, xx;        for(i=1; i<=n; i++)        {            for(j=0; j<(int)edg[i].size(); j++)            {               id=edg[i][j].id;               xx=edg[i][j].x;               if(dp[id].x==inf)continue;               if(dp[i].x>dp[id].x+abs(dp[id].pos-xx))               {                   dp[i].x=dp[id].x+abs(dp[id].pos-xx);                   dp[i].pos=xx;               }            }//            printf("%d\n", dp[i]);        }        printf("%d\n", dp[n].x+y);    }    return 0;}


原创粉丝点击