Help Jimmy POJ - 1661 数字三角DP
题意:中文 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的更多相关文章
- E - Help Jimmy POJ - 1661 dp
E - Help Jimmy POJ - 1661 这个题目本身不是很难,但是可以更加优化这个写法. 开始是n*n #include <cstdio> #include <cstri ...
- Help Jimmy POJ - 1661 dp
#include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> u ...
- POJ 1661 Help Jimmy(递推DP)
思路: 1. 每个板子有左右两端, dp[i][0], dp[i][1] 分别记录左右端到地面的时间 2. 从下到上递推计算, 上一层的板子必然会落到下面的某一层板子上, 或者地面上 总结: 1. 计 ...
- POJ 1661 Help Jimmy(C)动态规划
没刷过 POJ,这题是论坛有人问的,我才看看. 我发现 POJ 注册很奇怪,账号总是登不上去,弄的我还注册两个.Emmm 首次体验很差,还好我不在 POJ 刷题. 题目链接:POJ 1661 Help ...
- DP问题练习1:数字三角最短路径问题
DP问题练习1:数字三角最短路径问题 问题描述 给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上. 样例: 比如,给出下列数字三角形: 2 3 4 6 5 7 4 ...
- POJ.3624 Charm Bracelet(DP 01背包)
POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...
- 取数字(dp优化)
取数字(dp优化) 给定n个整数\(a_i\),你需要从中选取若干个数,使得它们的和是m的倍数.问有多少种方案.有多个询问,每次询问一个的m对应的答案. \(1\le n\le 200000,1\le ...
- 繁繁的数字 背包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+ ...
- POJ 2995 Brackets 区间DP
POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...
随机推荐
- matlab矩阵内存预分配
matlab矩阵内存预分配就意味着,划定一个固定的内存块,各数据可直接按"行.列指数"存放到对应的元素中.若矩阵中不预配置内存.则随着"行.列指数"的变大.MA ...
- Windows 7 无密码文件共享
Windows7中创建无密码的文件共享的几个步骤: 在“控制面板\所有控制面板项\网络和共享中心\高级共享设置”开启“关闭密码保护共享”和“启用文件和打印机共享”.关闭密码保护共享的操作会启用Gues ...
- MacOS的多重启动工具
在osx Lion升级到Mavericks后原有的refit(http://refit.sourceforge.net)启动管理工具就失效了,refit已经停止更新,新的分支项目时rEFInd(htt ...
- ios开发之--UIButton中imageView和titleLabel的位置调整
在使用UIButton时,有时候需要调整按钮内部的imageView和titleLabel的位置和尺寸.在默认情况下,按钮内部的imageView和titleLabel的显示效果是图片在左文字在右,然 ...
- Docker-创建和分享应用(3)
Dockerfile定义容器内环境中发生的事情.对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”哪些 ...
- EhCache初体验
一.简介 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点.Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,Java EE和轻量级容器.它具有内存和磁盘存 ...
- sqlite3常用指令
一.建立数据库 sqlite3.exe test.db 二.双击sqlite-3_6_16目录下的程序sqlite3.exe,即可运行 三.退出 .exit 或者 .quit 四.SQLite支持如下 ...
- python cookie
http://www.jayconrod.com/posts/17/how-to-use-http-cookies-in-python
- java.util.concurrent.RejectedExecutionException 线程池饱和
java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPoli ...
- Selenium 选项卡管理
什么是选项卡: from selenium import webdriver browser = webdriver.Chrome() browser.get("http://www.bai ...