E - Help Jimmy

POJ - 1661

这个题目本身不是很难,但是可以更加优化这个写法。

开始是n*n

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e3 + ;
int dp[maxn][];
struct node {
int l, r, h;
node(int x = , int y = , int h = ) :l(x), r(y), h(h) {}
}ex[maxn]; bool cmp(node a, node b) {
return a.h > b.h;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, x, y, maxs, ans = inf, flag = ;
memset(dp, inf, sizeof(dp));
scanf("%d%d%d%d", &n, &x, &y, &maxs);
for (int i = ; i <= n; i++) {
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
if (a > b) swap(a, b);
ex[i] = node(a, b, w);
}
sort(ex + , ex + + n, cmp);
for (int i = ; i <= n; i++) {
if (ex[i].l <= x && ex[i].r >= x && ex[i].h <= y) {
flag = ;
dp[i][] = y - ex[i].h + abs(ex[i].l - x);
dp[i][] = y - ex[i].h + abs(ex[i].r - x);
// printf("l=%d r=%d\n", ex[i].l, ex[i].r);
// printf("dp[%d]=%d dp[%d]=%d %d\n", i, dp[i][0], i, dp[i][1], ex[i].h);
break;
}
}
if (flag == && y <= maxs) {
printf("%d\n", y);
continue;
}
for (int i = ; i <= n; i++) {
int flag1 = , flag2 = ;
if (dp[i][] >= inf || dp[i][] >= inf) continue;
for (int j = ; j <= n; j++) {
if (i == j) continue;
if (ex[j].h > ex[i].h) continue;
int h = ex[i].h - ex[j].h;
if (h > maxs) continue; if (ex[i].l <= ex[j].r&&ex[i].l >= ex[j].l&&flag1 == ) {
flag1 = ;
dp[j][] = min(dp[j][], dp[i][] + abs(ex[i].l - ex[j].l) + h);
dp[j][] = min(dp[j][], dp[i][] + abs(ex[i].l - ex[j].r) + h);
// printf("l=%d l=%d h=%d\n", ex[i].l, ex[j].l, h);
// printf("ww dp[%d][0]=%d dp[%d][1]=%d %d\n", j, dp[j][0], j, dp[j][1], ex[j].h);
} if (ex[i].r <= ex[j].r&&ex[i].r >= ex[j].l&&flag2 == ) {
flag2 = ;
dp[j][] = min(dp[j][], dp[i][] + abs(ex[i].r - ex[j].l) + h);
dp[j][] = min(dp[j][], dp[i][] + abs(ex[i].r - ex[j].r) + h);
// printf("zz dp[%d][0]=%d dp[%d][1]=%d %d\n", j, dp[j][0], j, dp[j][1], ex[j].h);
} }
if (flag1 == && ex[i].h <= maxs) ans = min(ans, dp[i][] + ex[i].h);
if (flag2 == && ex[i].h <= maxs) ans = min(ans, dp[i][] + ex[i].h);
}
printf("%d\n", ans);
}
return ;
}

不把起点和终点当成平台的n*n

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e3 + ;
int dp[maxn][];
struct node {
int l, r, h;
node(int x = , int y = , int h = ) :l(x), r(y), h(h) {}
}ex[maxn]; bool cmp(node a,node b)
{
return a.h > b.h;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, x, y, maxs, ans = inf;
memset(dp, inf, sizeof(dp));
scanf("%d%d%d%d", &n, &x, &y, &maxs);
for (int i = ; i <= n; i++) {
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
if (w >= y) continue;
if (a > b) swap(a, b);
ex[i] = node(a, b, w);
}
ex[++n] = node(x, x, y);
ex[++n] = node(-inf, inf, );
sort(ex + , ex + + n, cmp);
dp[][] = , dp[][] = ;
for (int i = ; i <= n; i++) {
int flag1 = , flag2 = ;
if (dp[i][] >= inf || dp[i][] >= inf) continue;
for (int j = i+; j <= n; j++) {
if (ex[j].h >= ex[i].h) continue;
int h = ex[i].h - ex[j].h;
if (h > maxs) continue; if (ex[i].l <= ex[j].r&&ex[i].l >= ex[j].l&&flag1 == ) {
flag1 = ;
int val1 = abs(ex[i].l - ex[j].l);
int val2 = abs(ex[i].l - ex[j].r);
if (i == n || j == n) val1 = val2 = ;
dp[j][] = min(dp[j][], dp[i][] + val1 + h);
dp[j][] = min(dp[j][], dp[i][] + val2 + h);
// printf("l=%d l=%d h=%d\n", ex[i].l, ex[j].l, h);
// printf("ww dp[%d][0]=%d dp[%d][1]=%d %d\n", j, dp[j][0], j, dp[j][1], ex[j].h);
} if (ex[i].r <= ex[j].r&&ex[i].r >= ex[j].l&&flag2 == ) {
flag2 = ;
int val1 = abs(ex[i].r - ex[j].l);
int val2 = abs(ex[i].r - ex[j].r);
if (i == n || j == n) val1 = val2 = ;
dp[j][] = min(dp[j][], dp[i][] + val1 + h);
dp[j][] = min(dp[j][], dp[i][] + val2 + h);
// printf("zz dp[%d][0]=%d dp[%d][1]=%d %d\n", j, dp[j][0], j, dp[j][1], ex[j].h);
} }
}
printf("%d\n", min(dp[n][],dp[n][]));
}
return ;
}

把起点和终点当成平台的n*n

然后这个题目可以用线段树优化成 n*logn+n 的复杂度。

这个是因为每一个平台会落到的平台是固定的,所以可以用线段树预处理出来每一个平台的下一个平台。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int M = 2e4 + ;
const int maxn = 2e3 + ;
struct node
{
int id, l, r, lx, rx, y;
node(int id=,int l=,int r=,int lx=,int rx=,int y=):id(id),l(l),r(r),lx(lx),rx(rx),y(y){}
}ex[maxn];
int p[maxn];
ll dp[maxn][];
bool cmp(int a,int b)
{
return ex[a].y < ex[b].y;
}
bool cmp1(int a, int b) {
return ex[a].y > ex[b].y;
}
int sum[M * ], lazy[M * ]; void build(int id,int l,int r)
{
sum[id] = lazy[id] = ;
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
} void push_down(int id)
{
if (lazy[id] == ) return;
sum[id << ] = lazy[id];
sum[id << | ] = lazy[id];
lazy[id << ] = lazy[id << | ] = lazy[id];
lazy[id] = ;
} void update(int id,int l,int r,int x,int y,int val)
{
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
if(x<=l&&y>=r)
{
lazy[id] = val;
sum[id] = val;
return;
}
push_down(id);
int mid = (l + r) >> ;
if (x <= mid) update(id << , l, mid, x, y, val);
if (y > mid) update(id << | , mid + , r, x, y, val);
} int query(int id,int l,int r,int pos)
{
if (l == r) return sum[id];
int mid = (l + r) >> ;
push_down(id);
if (pos <= mid) return query(id << , l, mid, pos);
return query(id << | , mid + , r, pos);
} int main()
{
int t;
scanf("%d", &t);
while(t--)
{
memset(dp, inf, sizeof(dp));
int N, X, Y, H;
scanf("%d%d%d%d", &N, &X, &Y, &H);
X += M;
for(int i=;i<=N;i++)
{
p[i] = i;
int l, r, h;
scanf("%d%d%d", &l, &r, &h);
l += M, r += M;
ex[i] = node(i, l, r, , , h);
}
N++;
p[N] = N;
ex[N] = node(, -inf, inf, , , );
build(, , M * );
sort(p + , p + + N, cmp);
for(int i=;i<=N;i++)
{
// printf("i=%d p=%d\n", i, p[i]);
int l = ex[p[i]].l, r = ex[p[i]].r, id = ex[p[i]].id;
ex[p[i]].lx = query(, , M*, l);
ex[p[i]].rx = query(, , M*, r);
// printf("l=%d r=%d\n", l, r);
// printf("ex[%d] lx=%d rx=%d\n", p[i], ex[p[i]].lx, ex[p[i]].rx);
update(, , M*, l, r, id);
}
int num = query(, , M*, X);
if(num==)
{
printf("%d\n", Y);
continue;
}
dp[num][] = Y - ex[num].y + abs(X - ex[num].l);
dp[num][] = Y - ex[num].y + abs(X - ex[num].r);
// printf("num=%d\n", num);
// printf("dp[%d][0]=%lld dp[%d][1]=%lld\n\n", num, dp[num][0], num, dp[num][1]);
sort(p + , p + + N, cmp1);
for(int i=;i<=N;i++)
{
int id = ex[p[i]].id;
// printf("p[%d]=%d id=%d\n", i, p[i], id);
if (dp[id][] >= inf) continue;
int lx = ex[id].lx;
int rx = ex[id].rx;
if(ex[id].y-ex[lx].y<=H)
{
int val = abs(ex[id].l - ex[lx].l);
if (lx == ) val = ;
dp[lx][] = min(dp[lx][], dp[id][] + ex[id].y - ex[lx].y + val);
val = abs(ex[id].l - ex[lx].r);
if (lx == ) val = ;
dp[lx][] = min(dp[lx][], dp[id][] + ex[id].y - ex[lx].y + val);
}
if(ex[id].y-ex[rx].y<=H)
{
int val = abs(ex[id].r - ex[rx].l);
if (rx == ) val = ;
dp[rx][] = min(dp[rx][], dp[id][] + ex[id].y - ex[rx].y + val);
val = abs(ex[id].r - ex[rx].r);
if (rx == ) val = ;
dp[rx][] = min(dp[rx][], dp[id][] + ex[id].y - ex[rx].y + val);
}
// printf("dp[%d][0]=%lld dp[%d][1]=%lld\n", lx, dp[lx][0], lx, dp[lx][1]);
// printf("dp[%d][0]=%lld dp[%d][1]=%lld\n\n", rx, dp[rx][0], rx, dp[rx][1]);
}
printf("%lld\n", min(dp[][], dp[][]));
}
return ;
}

线段树 n*logn+n

还应该可以直接把dp放到线段树里面,就只有n*logn的复杂度。

这个暂时不想写了。

E - Help Jimmy POJ - 1661 dp的更多相关文章

  1. Help Jimmy POJ - 1661 dp

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

  2. Help Jimmy POJ - 1661 数字三角DP

    题意:中文 https://vjudge.net/problem/POJ-1661 题解:设两个dp数组,dpl[i]存 从第i块板左边到地上所花的最短时间,dpr[i]存右边的. 将所有板按高度排序 ...

  3. POJ 1661 DP

    Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11071   Accepted: 3607 Descr ...

  4. POJ 1661 Help Jimmy(递推DP)

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

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

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

  6. POJ 1661 Help Jimmy(二维DP)

    题目链接:http://poj.org/problem?id=1661 题目大意: 如图包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的 ...

  7. POJ - 1661 - Help Jimmy - 简单dp

    http://poj.org/problem?id=1661 一般化处理,把一开始的落地和大地都视作平台,设计平台类的属性.dp的时候显然是从上往下dp的,而且要小心Jimmy不能够穿过平台,也就是从 ...

  8. POJ 1661 Help Jimmy【DP】

    基础DP,过程想明白了其实也不复杂,从上面的推下面的比倒着推要简单很多.调试了半个多小时..简单dp依然不能快速AC..SAD.. 题目链接: http://poj.org/problem?id=16 ...

  9. POJ 1661 Help Jimmy LIS DP

    http://poj.org/problem?id=1661 对板按高度排序后. dp[i][0]表示现在站在第i块板上,向左跑了,的状态,记录下时间和其他信息. O(n^2)LIS: 唯一的麻烦就是 ...

随机推荐

  1. 002-IDE的使用与数据类型-C语言笔记

    002-IDE的使用与数据类型-C语言笔记 学习目标 1.[了解]IDE并熟悉Xcode基本使用技巧 2.[理解]C程序的入口和运行流程 3.[理解]变量的声明赋值和一些细节 4.[理解]变量的命名规 ...

  2. 【Tool】Windows系统安装Maven依赖管理工具

    安装Maven依赖管理工具 官网下载地址:http://maven.apache.org/download.cgi 系统环境要求: [JDK]Maven3.3版本+需要JDK1.7版本以上支持 [内存 ...

  3. 一站式WebAPI与认证授权服务

    保护WEBAPI有哪些方法? 微软官方文档推荐了好几个: Azure Active Directory Azure Active Directory B2C (Azure AD B2C)] Ident ...

  4. Android | 教你如何在安卓上实现二代身份证识别,一键实名认证

    @ 目录 前言 场景 开发前准备 android studio 安装 在项目级gradle里添加华为maven仓 在应用级的build.gradle里面加上SDK依赖 在AndroidManifest ...

  5. 格式化启动盘win10

    我这个(U盘)磁盘被分成了两个区,不能直接格式化 第一步: 第二步: 删除完了之后,选择格式化,ok. 说明:格式化时要选择系统. 常规NTFS  缺点:老设备,比如打印机,监控机识别不了. FAT系 ...

  6. [Abp vNext 入坑分享] - 1.创建初始的项目

    一.简要说明 本篇文章主要是跟着官方的文档把项目安装好先,同时了解一下大概的项目结构. 二.具体步骤 2.1全局安装ABP CLI,直接在cmd中安装即可.如果你之前安装过,这里可以略过: dotne ...

  7. .Net Core主机配置

    Host:(主机)负责web应用程序的启用和生成期管理,配置服务器和请求处理管道. 主机配置日志,依赖注入关系,实际上是一个封装了应用资源的对象. 创建主机生成器-〉配置主机-〉创建主机-〉运行主机. ...

  8. Java标识符中常见的命名规则

    标识符:就是给类,接口,方法,变量等起名字.组成规则:A:英文字母大小写B:数字字符C:$和_注意事项:A:不能以数字开头B:不能使Java中的关键字C:Java语言严格区分大小写常见的命名规则:见名 ...

  9. Java中接口的概念

    接口的特点: A:接口用关键字interface表示 interface 接口名 {} B:类实现接口用 implements 表示 class 类名 implements 接口名 {} C:接口不能 ...

  10. Java 虚拟机中的运行时数据区分析

    本文基于 JDK1.8 阐述分析 运行过程 我们都知道 Java 源文件通过编译器编译后,能产生相应的 .Class 文件,也就是字节码文件.而字节码文件通过 Java 虚拟机中的解释器,编译成特定机 ...