您的位置:首页 > 其它

poj 1661 Help Jimmy(DP)

2016-04-25 20:48 357 查看
题意:从起点走到地面的最短时间

分析:每一层只能由上面的掉下来,可能是上面的任何一层,那么反过来,上面的每一层只能由左端或者右端往下掉,掉到下面的某一层的左右端点包含上面这一层的左端或者右端,那么将这n个台阶按照从下往上排序。

dp[i][0]表示从下面到达第i层的左端花费最短的时间,dp[i][1]表示从下面到达第i层的右端花费的最短的时间。

dp[i][0] = min(dp[L][0]+step[i].l-step[L].l, dp[L][1]+step[L].r-step[i].l)+step[i].h-step[L].h;

dp[i][1] = min(dp[R][0]+step[i].r-step[i].l, dp[R][1]+step[R].r-step[i].r)+step[i].h-step[R].h;

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <algorithm>

using namespace std;

const int oo = 1e9;

struct Step
{
int l, r, h;
}step[2005];

bool cmp(Step a1, Step a2)
{
return a1.h<a2.h;
}
int dp[2002][2];

int main()
{
int t;
int n, x, y, Max;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &x, &y, &Max);
step[0].l = step[0].r = x;
step[0].h = y;
dp[0][0] = dp[0][1] = oo;
for(int i=1; i<=n; i++)
{
scanf("%d%d%d", &step[i].l, &step[i].r, &step[i].h);
dp[i][0]=oo;
dp[i][1]=oo;
}
sort(step, step+n+1, cmp);
int ls, rs;
for(int i=0; i<=n; i++)
{
ls = rs = -1;
for(int j=0; j<i; j++)
{
if(step[j].l<=step[i].l&&step[j].r>=step[i].l)
ls = j;
if(step[j].l<=step[i].r&&step[j].r>=step[i].r)
rs = j;
}
if(ls==-1 && step[i].h<=Max)//直接从第i层跳到地面
dp[i][0] = step[i].h;
if(rs==-1 && step[i].h<=Max)//同上
dp[i][1] = step[i].h;

if(ls!=-1 && step[i].h - step[ls].h <= Max)
dp[i][0] = min(dp[ls][0]+step[i].l-step[ls].l, dp[ls][1]+step[ls].r-step[i].l)+step[i].h-step[ls].h;

if(rs!=-1 && step[i].h - step[rs].h <= Max)
dp[i][1] = min(dp[rs][0]+step[i].r-step[rs].l, dp[rs][1]+step[rs].r-step[i].r)+step[i].h-step[rs].h;
}

printf("%d\n", dp
[0]);//dp
[1]=dp
[0]
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: