题意:中文 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 + ; 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 == ) return ;
else for (int i = now-; i >=; i--) {
if (p[i].h == p[now].h)continue;//改:同高度//其实不用考虑
if (p[i].l <= x&&p[i].r >= x) return i;
}
return ;//直接掉到地上
}
//大改:算法错误。
int main()
{
int t;
cin >> t;
while (t--) {
_for(i, , N) dpl[i]=dpr[i] = 1e9;
int n, x, y, mn;
cin >> n >> x >> y >> mn;
_for(i, , n+) {cin >>p[i].l>>p[i].r>>p[i].h;}
p[n+].l = p[n+].r = x; p[n+].h = y;
p[].l = -2e6; p[].r = 2e6; p[].h = ; //改:考虑掉到地上,不能这样改。
sort(p, p + n+,cmp);
//查找落到下面的那一块:可以排序后二分
_for(i, , n+) {
int idl= find(p[i].l,i), idr= find(p[i].r,i);
if (idl == ) { 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 == ) { 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 + ;
int idl = find(p[i].l, i);
if (idl == ) { 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+]<<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 + ;
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 == ) return ;
else for (int i = now-; i >=; i--) {
if (p[i].h == p[now].h)continue;//改:同高度
if (p[i].l <= x&&p[i].r >= x) return i;
}
return ;//直接掉到地上
}
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+; 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] == -)dpl[i] = dpfun(i, true);
if (L[i] == -)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, , N) dpl[i] = dpr[i] =L[i]= -; cin >> n >> x >> y >> mn;
_for(i, , n + ) { cin >> p[i].l >> p[i].r >> p[i].h; } p[].l = x; p[].r = x; p[].h = y; //改:考虑掉到地上,不能这样改。
sort(p, p + n + );
//查找落到下面的那一块:可以排序后二分
cout << dpfun(, true) << endl;
}
system("pause");
}

Help Jimmy POJ - 1661 数字三角DP的更多相关文章

  1. E - Help Jimmy POJ - 1661 dp

    E - Help Jimmy POJ - 1661 这个题目本身不是很难,但是可以更加优化这个写法. 开始是n*n #include <cstdio> #include <cstri ...

  2. Help Jimmy POJ - 1661 dp

    #include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> u ...

  3. POJ 1661 Help Jimmy(递推DP)

    思路: 1. 每个板子有左右两端, dp[i][0], dp[i][1] 分别记录左右端到地面的时间 2. 从下到上递推计算, 上一层的板子必然会落到下面的某一层板子上, 或者地面上 总结: 1. 计 ...

  4. POJ 1661 Help Jimmy(C)动态规划

    没刷过 POJ,这题是论坛有人问的,我才看看. 我发现 POJ 注册很奇怪,账号总是登不上去,弄的我还注册两个.Emmm 首次体验很差,还好我不在 POJ 刷题. 题目链接:POJ 1661 Help ...

  5. DP问题练习1:数字三角最短路径问题

    DP问题练习1:数字三角最短路径问题 问题描述 给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上. 样例: 比如,给出下列数字三角形: 2 3 4 6 5 7 4 ...

  6. POJ.3624 Charm Bracelet(DP 01背包)

    POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...

  7. 取数字(dp优化)

    取数字(dp优化) 给定n个整数\(a_i\),你需要从中选取若干个数,使得它们的和是m的倍数.问有多少种方案.有多个询问,每次询问一个的m对应的答案. \(1\le n\le 200000,1\le ...

  8. 繁繁的数字 背包DP

    繁繁的数字 背包DP 问一个数\(n\)有多少种二进制分解方案数 \(n\le 10^5\) 如7有7=4+2+1=4+1+1+1=2+2+2+1=2+2+1+1+1=2+1+1+1+1+1=1+1+ ...

  9. POJ 2995 Brackets 区间DP

    POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...

随机推荐

  1. 如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数

    方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化.如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环 ...

  2. polarssl rsa & aes 加密与解密

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  3. [NodeJS] Node.js 与 V8 的故事

    要说Node.js的历史,就不得不说说V8历史.在此之前我们先一句话描述一下什么是Node.js:Node.js是一个基于Google Chrome V8 Javascript引擎之上的平台,用以创建 ...

  4. codeforces水题100道 第二十五题 Codeforces Round #197 A. Helpful Maths (Div. 2) (strings)

    题目链接:http://www.codeforces.com/problemset/problem/339/A题意:重新组合加法字符串,使得按照1,2,3的顺序进行排列.C++代码: #include ...

  5. <转>Python: __init__.py 用法

    转自 http://www.cnblogs.com/BeginMan/p/3183629.html python的每个模块的包中,都有一个__init__.py文件,有了这个文件,我们才能导入这个目录 ...

  6. purge recyclebin之后dba_segments仍然有BIN$段

    现象: purge recyclebin之后dba_segments仍然有BIN$段. 如下,执行了purge recyclebin之后: SQL> select segment_name,SE ...

  7. 【转】C++可变参数列表处理宏va_list、va_start、va_end的使用

    VA_LIST是在C语言中解决变参问题的一组宏他有这么几个成员: 1)va_list型变量: #ifdef     _M_ALPHA typedef    struct{ char* a0; /*po ...

  8. google v8引擎常见问题

    最近在项目中使用v8来进行扩展,下面简单说一下使用v8过程中遇到的一些问题.   v8的多线程调用 最初调研v8的测试代码是单线程的,后来一个项目在多线程中使用,出现了一些问题,后来看到参考3中的才恍 ...

  9. 二、Laya学习笔记 ---- Laya中如何新建一个场景UI并使用

    因为我之前是用Egret的,Egret是场景皮肤HomeSceneSkin.exml,然后在场景代码HomeScene代码中为该场景赋值皮肤this.skinName = "HomeScen ...

  10. win7下桌面右键一直转圈圈的解决方法

    今天公司同事的电脑,在进入win7系统后,桌面右键一直转圈圈,找我解决这个问题. 经过我观察,他电脑只是在桌面上右键有此现象,在其他地方并无此现象. 因此可以得出结论,此现象很可能与桌面右键有关,经上 ...