题意:中文 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. NetBpm 测试篇(3)

    http://www.netbpm.org/movie/holiday/holiday.html

  2. Git 学习笔记--Git下的冲突解决

    冲突的产生 很多命令都可能出现冲突,但从根本上来讲,都是merge 和 patch(应用补丁)时产生冲突. 而rebase就是重新设置基准,然后应用补丁的过程,所以也会冲突. git pull会自动m ...

  3. mysql类型对应Java的类型

    整型 JDBCtinyint         java.lang.Integersmallintmediumint       java.lang.Longint          bigint    ...

  4. java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available

    好久没有使用MyEclipse10了,今天打开看了以前大学的项目,在Tomcat7中发布启动,我嚓嘞,报错: SEVERE: Exception initializing random number ...

  5. iOS10个实用小技巧(总有你不知道的和你会用到的)

    本文转载至 http://www.jianshu.com/p/a3156826c27c 在开发过程中我们总会遇到各种各样的小问题,有些小问题并不是十分容易解决.在此我就总结一下,我在开发中遇到的各种小 ...

  6. spring配置文件中xsd引用问题

    XML的一些概念 首先来看下xml的一些概念: xml的schema里有namespace,可以给它起个别名.比如常见的spring的namespace:   xmlns:mvc="http ...

  7. JS中方法判断存在

    function test(){ alert("test"); } if(typeof test!='undefined') {alert(1) test(); } else {a ...

  8. jQuery().end()的内部实现及源码分析

    jQuery().end()的作用是返回当前jQuery对象的上一个状态. 1.end()源码: // 所有通过pushStack方法获得的jQuery对象都可以通过end方法返回之前的状态   // ...

  9. html5里面的延迟加载属性

    html5中给script标签引入了 async 和 defer 属性. 原理:带有async属性的script标签,会在浏览器解析时立即下载脚本同时不阻塞后续的document渲染和script加载 ...

  10. POJ 3273 Monthly Expense(二分答案)

    Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36628 Accepted: 13620 Des ...