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. cmake添加版本号

    vVersion.cmake文件内容如下: #vversion.cmake #vDateTime string(TIMESTAMP vDateTime "%Y%m%d-%H%M%S" ...

  2. Property [*****] not found on type [com.erp.pojo.ErpSupplier]

    我实体类里用的是 springboot 里@Slf4j   @Data  注解式写的  这样可以减少代码量 ,但是遇到一个问题影响我好长时间 出现了这个错误  Property [*****] not ...

  3. .net批量更新(插入、修改、删除)数据库

    思路: 1. 设置DataTable中每行的状态标识,即调用DataRow的方法setAdded().setModified().Delete() 2. 使用DataAdapter的Update(Da ...

  4. The Super Powers UVA - 11752

    题目大意:将范围从1~pow(2,64)-1内的super power输出.super power的定义:一个数x至少存在两种x=pow(i,k),(k!=1). 题解: 注意数据范围2的64次方-1 ...

  5. X - Ehab and Path-etic MEXs CodeForces - 1325C

    MMP,差一点就做对了. 题目大意:给你一个树,对这个树的边进行编号,编号要求从0到n-1,不可重复,要求MEX(U,V)尽可能的小, MEX(x,y)的定义:从x到y的简单路径上,没有出现的最小编号 ...

  6. A Bug's Life POJ 2492

    D - A Bug's Life 二分图 并查集 BackgroundProfessor Hopper is researching the sexual behavior of a rare spe ...

  7. Laravel 分页 数据丢失问题解决

    问题: to do list 中有32条数据,每页10条,共3页. 做完了一个事项之后,准备打卡,发现找不到这个事项. 数据库查询正常,有这一条数据. 原因: 发现是分页出了问题,第1页的数据和第2页 ...

  8. 数据源管理 | PostgreSQL环境整合,JSON类型应用

    本文源码:GitHub·点这里 || GitEE·点这里 一.PostgreSQL简介 1.和MySQL的比较 PostgreSQL是一个功能强大的且开源关系型数据库系统,在网上PostgreSQL和 ...

  9. springboot+dubbo简单分布式RPC调用demo

    使用springboot+dubbo搭建RPC入门案例 本文背景简述: 最近在学习公司的一套RPC框架,初步接触的时候感觉挺复杂的.但是知道其原理肯定是和dubbo很相似的,毕竟都是RPC框架嘛,只是 ...

  10. 免费申请通配符类型SSL证书

    折腾起因 最近做了个小网站wawoo.fun,一个做mac壁纸的小网站,网站还处在初级阶段,不能跟大神的比.网站发布后发现因为没有使用https,谷歌浏览器会在地址栏提示网站不安全.因此想提升下网站的 ...