#10178. 「一本通 5.5 例 4」旅行问题

Posted lovedsr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#10178. 「一本通 5.5 例 4」旅行问题相关的知识,希望对你有一定的参考价值。

题目

loj链接

思路

瞎jb写,考试最后5min找到bug,考玩10minAC,成功GG

这题没啥算法(感觉跟dp有点关系?)

他们说正解是单调队列,鬼知道咋用,反正我是O(n)

题目数据最大好像是1e5,大家也可以写个O(nlogn)的水一水拉

就是预处理个 f1 ,f2,代码里的注释很详细了

也不想说啥了,伤心╮(╯﹏╰)╭

#include <iostream>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
const int maxn=1e6+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n,a[maxn],nxt[maxn];
ll f1[maxn],f2[maxn],sum_jia[maxn],sum_jian[maxn];
bool is_ok[maxn];
ll min(ll a,ll b) {
    return a < b ? a: b;
}
int read() {
    int x=0,f=1;
    char s=getchar();
    for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1;
    for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0';
    return x*f;
}
int main() {
    n=read();
    for(int i=1; i<=n; ++i) {
        a[i]=read(),nxt[i]=read();
        sum_jia[i]=sum_jia[i-1]+a[i];
        sum_jian[i]=sum_jian[i-1]+nxt[i];
    }
    //f1 表示 从 1 出发 到达 i 的最少初始值
    ll sheng=0,ma=-inf;
    for(int i=2; i<=n; ++i) {
        sheng+=a[i-1]-nxt[i-1];
        ma=max(ma,-sheng);
        f1[i]=ma;
    }
    
    //f2 表示 从 i 出发 到达 n 的最少初始值
    for(int i=n-1; i>=1; --i)
        f2[i]=min(f2[i+1]+a[i]-nxt[i],a[i]-nxt[i]);
    for(int i=1; i<=n; ++i)
        f2[i]*=-1;
    
    //顺时针
    for(int i=1; i<=n; ++i) {
        if(f2[i] > 0) continue; 
        ll tmp1=sum_jia[n] - sum_jia[i-1];
        ll tmp2=sum_jian[n] - sum_jian[i-1];
        ll zzz=tmp1-tmp2;
        if(zzz < f1[i]) continue;
        is_ok[i]=1;
    }
    
    
    //清空 
    memset(f1,0,sizeof(f1));
    memset(f2,0,sizeof(f2));
    
    
    //f1 表示 从 n 出发 到达 i 的最少初始值
    sheng=0,ma=-inf;
    for(int i=n-1; i>=1; --i) {
        sheng+=a[i+1]-nxt[i];
        ma=max(ma,-sheng);
        f1[i]=ma;
    }

    //f2 表示 从 i 出发 到达 1 的最少初始值
    for(int i=2; i<=n; ++i)
        f2[i]=min(f2[i-1]+a[i]-nxt[i-1],a[i]-nxt[i-1]);
    for(int i=1;i<=n;++i)
        f2[i]*=-1;

    //逆时针
    for(int i=1; i<=n; ++i) {
        if(f2[i] > 0) continue;
        ll tmp1=sum_jia[i];
        ll tmp2=sum_jian[i-1];
        ll zzz=tmp1-tmp2;
        if(zzz-nxt[n] < max(f1[i],0LL)) continue;
        is_ok[i]=1;
    }

    //输出 
    for(int i=1; i<=n; ++i) {
        if(is_ok[i]) puts("TAK");
        else puts("NIE");
    }
    return 0;
}

以上是关于#10178. 「一本通 5.5 例 4」旅行问题的主要内容,如果未能解决你的问题,请参考以下文章

单调队列优化DP 旅行问题 LibreOJ - 10178

#10131 「一本通 4.4 例 2」暗的连锁

一本通1555例 4次小生成树

#10181. 「一本通 5.5 练习 2」绿色通道

#10114 「一本通 4.1 例 2」数星星 Stars

loj10143. 「一本通 4.6 例 1」营业额统计