题意:中文 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. RHEL5 yum更新源

    1.检查yum是否安装 rpm -qa |grep yum 2.利用CentOS的yum更新源来实现RHEL5的YUM功能 vi /etc/yum.repos.d/CentOS-Base.repo [ ...

  2. css counter的使用方法

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 品鉴同事发来的炸金花的PHP程序代码

    今天同事发来了一个炸金花的PHP程序,这个代码实现了两个人通过各自的三张牌进行权重计算,得到分数进行比较得到谁的牌大,我觉得里面还有一些问题,代码如下: <?php /** 每张牌的分值为一个2 ...

  4. form enctype:"multipart/form-data",method:"post" 提交表单,后台获取不到数据

    在解决博问node.js接受参数的时候,发现当form中添加enctype:"multipart/form-data",后台确实获取不到数据,于是跑到百度上查了一下,终于明白为什么 ...

  5. httpClient创建对象、设置超时

    从老版本和新版本进行比较说明: 1.创建HttpClient对象 3.X: HttpClient httpClient = new DefaultHttpClient(); 4.3: Closeabl ...

  6. Ansible Playbook 简介

    我们去远程执行命令时要使用 command 模块,拷贝文件时要使用 copy 模块,如果我们要操作的东西很多,那就要执行很多条不同模块的命令Playbook 是一个 yaml 配置文件,我们可以把不同 ...

  7. Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2

    原因是解析的时候多了,逗号,或是 \ 解决方法:一 revJson=revJson.replace("\\", "");//去掉'/' revJson=revJ ...

  8. 在RDLC报表中对纸张的设置

    RDLC报表是存放成XML文件格式的,这一点你可以直接打开RDLC报表文件看一下,而且在使用时,通过ReportViewer来读取报表并与数据源进行合成,也就是说RDLC是定义了一个格式,那就不能通过 ...

  9. mysql 创建merge表方便查询

    SELECT COUNT(*) FROM `comment` SHOW CREATE TABLE `comment` CREATE TABLE `comment1` ( `id` ) NOT NULL ...

  10. no matching function for call to ‘std::basic_string<char>::assign(std::string&, int)

    使用string中的assign赋值函数报错,代码为: text0.assign(line,i+); 其中text0与line都为string类型 最后发现assign函数的原型为 string &a ...