首页 > 其他分享 >旅行问题

旅行问题

时间:2022-09-20 22:55:43浏览次数:65  
标签:旅行 油量 int tt ++ 问题 -- hh

单调队列优化DP

原题链接

题目描述:

给定一个环,环上每个节点有一个油量,当车开到这个节点时可以获得该点的油量,该点还有一个值di表示车从i点开到i+1点所耗费的油量,现有一辆车想从任一起点出发,初始可以获得起点的油量,可以选择顺时针走一圈或逆时针走一圈,行驶过程中没油不行,问能否完成环球旅行

分析

先将环拆成链

顺时针

假设a[i]表示点i在i点加了油之后再减去到达下一站所需的耗油量剩余的油量,即w[i]-d[i]
从点i出发,能走一圈的前提是任意时刻剩余的油量>=0 ,等价于在[i,i+n-1]中,对任意ji<=j<=i+n-1,均有s[j]-s[i-1]>=0,即找到最小的s[j],若最小的s[j]都满足条件,则i一定可以走一圈回到起点,即在[i,i+n-1]窗口中找到最小值,

逆时针

道理相同,方向相反,求后缀和,对[i-n+1,i]窗口中的最小值s[j],有s[j]-s[i+1]>=0即可

Code

#include <iostream>
#include <cstring>

using ll = long long;

const int N = 1e6 + 5;

int w[N], d[N];
int q[N];
ll s[N << 1];
bool success[N];

int main() {
    int n;
    std::cin >> n;
    for (int i = 1; i <= n; i ++ ) std::cin >> w[i] >> d[i];
    
    // 顺时针
    for (int i = 1; i <= n; i ++ ) s[i] = s[i + n] = w[i] - d[i];
    for (int i = 1; i <= n * 2; i ++ ) s[i] += s[i - 1];
    
    int hh = 0,tt = -1;
    for (int i = n * 2; i >= 1; i --) {
        if (hh <= tt && q[hh] > i + n - 1) hh ++;
        while(hh <= tt && s[q[tt]] >= s[i]) tt --;
        q[++ tt] = i;
        // 只做i<=n时的即可
        if (i <= n && s[q[hh]] - s[i - 1] >= 0) success[i] = true;
    }
    
    // 逆时针
    d[0] = d[n];
    for (int i = 1; i <= n; i ++ ) s[i] = s[i + n] = w[i] - d[i - 1];
    for (int i = n * 2; i >= 1; i -- ) s[i] += s[i + 1];
    
    hh = 0, tt = -1;
    for (int i = 1; i <= n * 2; i ++ ) {
        if (hh <= tt && q[hh] < i - n + 1) hh ++ ;
        while (hh <= tt && s[q[tt]] >= s[i]) tt -- ;
        q[ ++ tt] = i;
        // 只做i>n时的即可
        if (i > n && s[q[hh]] - s[i + 1] >= 0) success[i - n] = true;
    }
    
    for (int i = 1; i <= n; i ++ ) puts(success[i] ? "TAK" : "NIE");
    return 0;
}

标签:旅行,油量,int,tt,++,问题,--,hh
From: https://www.cnblogs.com/zjh-zjh/p/16712964.html

相关文章

  • g++ 编译顺序问题
    转自:https://blog.csdn.net/sunny04/article/details/17913949https://cloud.tencent.com/developer/article/11787531.问题g++-lxxxmain.cpp-omain//报错un......
  • Mac系统用Maven本地引入jar包报错问题解决
    打包命令mvninstall:install-file-Dfile=/Users/用户名/tool/selenium-server-standalone-3.9.1.jar-DgroupId=org.selenium-DartifactId=selenium-server-standalone......
  • T1036:A*B问题(信息学一本通C++)
     目录[题目描述]输入两个正整数A和B,求A*B的值。注意乘积的范围和数据类型的选择。[输入]一行,包含两个正整数A和B,中间用单个空格隔开。1≤A,B≤50000。[输出]两......
  • zookeeper一键启动脚本编写问题
    该脚本zk.sh为#!/bin/bashcase$1in"start"){foriinnode1node2node3doecho----------------------zookeeper$i启动---------......
  • C#处理读取使用US7ASCII的oracle数据库中文显示乱码问题
    方式一:(推荐)OracleDataAccessComponents(ODAC)+OleDbConnection该方式无需配置环境变量1、下载ODAC组件,地址为https://www.oracle.com/technetwork/topics/dotne......
  • 双胞胎素数问题
     较为基础代码如下1#include<stdio.h>2intfun(intn)3{4inti;5for(i=2;i<n;i++)6if(n%i......
  • CSP-S模拟7 序列问题 钱仓 自然数 环路
    T1:线性DP,求最长不下降子序列优化(cdp,树状数组)T2:断环为链,结论T3:序列上区间统计答案,线段树维护T4:咕了,矩阵乘法+分治优化,我就打个暴力T1:给你一个长度n的序列A(n<=5e5,ai<=......
  • python:islice一次读取N行的问题
    Python:ProblemswithislicetoreadNnumberoflinesatatimefromitertoolsimportisliceN=16infile=open("my_very_large_text_file","r")lines_gen......
  • 组合问题看透回溯法
    通过组合问题看透回溯法前言已经好久没有更新了......
  • javascript的API和跨域问题
    document.getElementById(),根据ID来精确查找元素document.querySelectorAll(),根据选择器来查找,返回一个或者多个元素document.querySelector(),根据选择器来查找,同类多个......