Codeforces Round #577 (Div. 2)  D. Treasure Hunting

这个一场div2 前面三题特别简单,这个D题的dp还是比较难的,不过题目告诉你了只能往上走,所以还是可以看出来这个是一个dp的。

然后对于每一段,肯定是从左到右或者从右到左这个是最优的,这里就是有一点点贪心的思想。

所以要我们首先要求出每一行的最大最小,然后就是开始转移。

题目要求只有一部分的列才可以竖直方向的走,这个让我就有点迷糊。

首先每一段向下转移,如果这个位置向下转移到的那个位置直接有直线可以竖着的走,

那么可以知道这个肯定是最优的,如果没有就只能找两边的了。

这个其实有点难写,看了别人的代码发现,这个可以用lower_bound 和 upper_bound 很巧妙的解决。

首先在一个数组里面存下可以走的每一列,然后还要存一个最小值-inf,和一个最大值 inf。然后排序一下。

然后就是找对于每一个区间,就是刚刚说的那个转移区间,(x,y) 注意 x不一定小于等于y

我们开始用lower_bound 找到大于等于x的最大值,如果没有大于等于x的那么就会找到inf,这个很自然会被舍去,然后upper_bound 就会找到区间左边的,

如果找到了大于等于的,那么用upper_bound会找到相同的位置,然后-1就是区间左边的,这个时候就判断一下,选哪个更优。

如果y>y 也是一样的,这个lower_bound 会找到两边的,如果中间有那么upper_bound也会找到。

这个之后还要加一点点东西,竖直距离和max[i]-min[i]

#include <cstring>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 2e5 + ;
typedef long long ll;
int Max[maxn], Min[maxn], num[maxn], cnt;
ll dp[maxn][]; ll dis(int x,int y)
{
int l = *(lower_bound(num + , num + + cnt, x));
int r = *(upper_bound(num + , num + + cnt, x) - );
return min(abs(x - l) + abs(y - l), abs(x - r) + abs(y - r));
} int main()
{
int n, m, k, q, ans = ;
scanf("%d%d%d%d", &n, &m, &k, &q);
memset(Min, inf, sizeof(Min));
for(int i=;i<=k;i++)
{
int l, r;
scanf("%d%d", &l, &r);
Max[l] = max(Max[l], r);
Min[l] = min(Min[l], r);
ans = max(ans, l);
}
for(int i=;i<=q;i++)
{
int x;
scanf("%d", &x);
num[i] = x;
}
cnt = q;
num[++cnt] = inf; num[++cnt] = -inf;
sort(num + , num + + cnt);
if(Max[]==) Max[] = , Min[] = ;
dp[][] = Max[] * - Min[] - ;
dp[][] = Max[] - ;
//printf("ww %lld %lld\n", dp[1][0], dp[1][1]);
int x = ;
for(int i=;i<=n;i++)
{
//printf("i=%d\n", i);
if (Max[i] == ) continue;
dp[i][] = min(dis(Min[x], Max[i]) + dp[x][], dis(Max[x], Max[i]) + dp[x][]);
dp[i][] = min(dis(Min[x], Min[i]) + dp[x][], dis(Max[x], Min[i]) + dp[x][]);
//printf("dp[%d][0]=%lld dp[%d][1]=%lld\n", i, dp[i][0], i, dp[i][1]);
dp[i][] += abs(Max[i] - Min[i]) + i - x;
dp[i][] += abs(Max[i] - Min[i]) + i - x;
x = i;
//printf("dp[%d][0]=%lld dp[%d][1]=%lld\n", i, dp[i][0], i, dp[i][1]);
}
//printf("ans=%d\n", ans);
printf("%lld\n", min(dp[ans][], dp[ans][]));
return ;
}

Codeforces Round #577 (Div. 2) D. Treasure Hunting的更多相关文章

  1. Codeforces Round #577 (Div 2)

    A. Important Exam 水题 #include<iostream> #include<string.h> #include<algorithm> #in ...

  2. 矩阵拿宝物--Codeforces 1201D - Treasure Hunting Codeforces Round #577 (Div. 2)

    网上题解比较少,自己比较弱研究了半天(已经过了),希望对找题解的人有帮助 题目链接:https://codeforc.es/contest/1201/problem/D 题意: 给你一个矩形,起始点在 ...

  3. Codeforces Round #282 (Div. 1) A. Treasure 水题

    A. Treasure Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/494/problem/A ...

  4. 【枚举】【贪心】Codeforces Round #482 (Div. 2) B. Treasure Hunt

    题意:给你3个字符串,3个人各对自己的字符串执行n轮操作,每一次选择一个字符变为任意一个和原来不同的字符.最后问你谁能使自己的串中的任意重复子串出现的次数最大化. 显然只需关注字符而非子串. 枚举每个 ...

  5. Codeforces Round #577 (Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1201 A. Important Exam 题意:有\(n\)个人,每个人给出\(m\)个答案,每个答案都有一个分值\(a_i\), ...

  6. Codeforces Round #577 (Div. 2) C. Maximum Median (模拟,中位数)

    题意:给你一个长度为奇数\(n\)的序列.你可以对任意元素加上\(k\)次\(1\),求操作后的中位数最大. 题解:先对序列进行排序,然后对中位数相加,如果中位数和后面的元素相等,就对后面所有和当前中 ...

  7. Codeforces Round #577 (Div. 2) C. Maximum Median

    题意:就是给一n(奇数)个元素数组,可以对它的元素执行k次+1操作,递增排序,求中位数最大是多少. 那我们在排完序之后,中位数前的元素可以不管它,只要对中位数后的操作就行,我们要判断和中位数相等的元素 ...

  8. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  9. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

随机推荐

  1. Daily Scrum 1/7/2015

    Process: Zhaoyang: Do some code intergration and test the total feature in the IOS APP. Yandong: Cod ...

  2. Python刷CSDN阅读数(仅供娱乐)

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ @File:csdn_reads.py @E-mail:3649427 ...

  3. 关于Python+selenium 定位浏览器弹窗元素

    首先要确定弹窗的类型: (1)div弹窗 (2)新标签页弹窗 (3)alert弹窗 一,div弹窗div弹窗是浏览器中比较好定位的弹窗,定位的方法与普通的元素一样.不过这里会有一个坑,明明可以找到这个 ...

  4. 详解 Arrays类

    请关注本人博文--<详解 普通数组 -- Arrays类 与 浅克隆> Arrays类: 概述: 针对数组进行操作的工具类.它提供了对于数组的值的排序.查找等功能. 现在,本人来展示一下A ...

  5. 详解 I/O流

    I/O流是用于处理设备之前信息传输的流,在我们今后的学习甚至是工作中,都是十分重要的. 在我们的日常生活中,也是很常见的,譬如:文件内容的合并.设备之键的文件传输,甚至是下载软件时的断点续传,都可以用 ...

  6. Springboot:员工管理之查询员工列表(十(6))

    构建员工controller com\springboot\controller\EmployeeController.java package com.springboot.controller; ...

  7. Unity Procedural Level Generator 基础总结与功能优化

    Procedural Level Generator是在Unity应用商店中发布的一款免费的轻量级关卡生成器: 可以直接搜索关键字在应用商店中查找并下载. 和我之前生成关卡的想法不同,这个插件生成地图 ...

  8. ES6中的let关键字,有什么用呢?

    来吧,开始本节的学习! ES6 给开发者带来很多令人激动的特性,其中let关键字就是其中之一. 那么,let关键字是什么东西? let 的用途 我们回想一下,我们平时在写代码的时候,用var来声明一个 ...

  9. thinkphp5.1+ 使用 Redis 缓存

    修改 config/cache.php 将其配置成多个缓存类型,示例 <?php // +---------------------------------------------------- ...

  10. CentOS 7 + Win 双系统的安装遇到的重要问题

    前言:对于刚学linux的朋友们,多多小小因为各种原因需要装双系统,亦或者爱好使然.多数是问题解决,第一次装系统者不推荐看-. 那么现在内德在此就说说在本本上装双系统会遇到的问题及其解决方法. 环境准 ...