POJ1661

来源:互联网 发布:最优化方法推荐 编辑:程序博客网 时间:2024/06/06 07:52

题目链接

jimmy要从上开始往下落使得时间最少,所以可以看为从左边走和右边走的从这两个子问题中寻找最优解 设DP[n][0]为从左边走获得的最短时间DP[n][1]为从右边走获得最短时间 但是因为Jimmy开始所处的位置为一个点没有左右之分所以最终的结果DP[n][0]=DP[n][1] 时间相等

#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 2000;int t, n, l, r, maxh;int dp[maxn][2];struct kim{    int l, r, h;    bool operator < (const kim &k) //对平台的高度从小到大排序    {        return h < k.h;    }}node[maxn];int main(){    scanf("%d", &t);    while (t--)    {        memset(dp, 0x3f3f3f3f, sizeof(dp));        scanf("%d%d%d%d", &n, &l, &r, &maxh);        for (int j = 0; j < n; j++)            scanf("%d%d%d", &node[j].l, &node[j].r, &node[j].h);        node[n].l = l;        node[n].r = l;        node[n].h = r;        sort(node, node + n);        int lp, rp;        for (int j = 0; j <= n; j++)        {            lp = rp = -1;            for (int k = j - 1; k >= 0; k--)            {                if (lp == -1 && node[k].l <= node[j].l && node[k].r >= node[j].l) //如果左下方有平台可以下落                    lp = k;                if (rp == -1 && node[k].l <= node[j].r && node[k].r >= node[j].r) //如果右下方有平台可以下落                    rp = k;            }            if (lp == -1&&node[j].h<=maxh)//两个平台高度差小于指定差maxh                dp[j][0] = node[j].h;            if (rp == -1&&node[j].h<=maxh)                dp[j][1] = node[j].h;            if (lp != -1 && node[j].h - node[lp].h <= maxh)                dp[j][0] = min(dp[lp][0] + node[j].l - node[lp].l, dp[lp][1] + node[lp].r - node[j].l) + node[j].h - node[lp].h; //下落到平台考虑往左边还是往右边走 选最小值            if (rp != -1 && node[j].h - node[rp].h <= maxh)                dp[j][1] = min(dp[rp][1] + node[rp].r - node[j].r, dp[rp][0] + node[j].r - node[rp].l) + node[j].h - node[rp].h;        }        cout << dp[n][0]<< endl;    }    //system("pause");}
原创粉丝点击