• BZOJ3827: [Poi2014]Around the world && CF526E Transmitting Levels


    要求的东西是一样的,感觉 poi 的题面要比 cf 的题面容易想一些

    首先贪心的从每个点往后尽可能跳的远,
    如果能跳肯定是越远越好,如果不能跳那无论如何都不合法了

    先破环成链

    从前往后每个点能跳到的最远位置显然是单调的,可以 O(n) 求


     为了便于思考,倒着考虑,计算从一个点往回能到哪

    这是和正着做是一样的,想要能到一个点只要能跳过他就行
    正着计算只要倒着推应该也是可以的
    每个点向前唯一对应一个来的点,像是一个树形结构(有的题解是这么写的反正我也没想到)

    这样方便从前往后顺序枚举并从前边的状态转移过来,f[i] = f[pre_i] + 1

    设复制的一段都是终止点,之前的一段都是起始点

    这样就可以递推出解了,没有什么决策的

    只要从后面一段开始计算最远往前能到哪就好了,每次从前边的继承

    每次判断一下从这个位置往前最远能到的位置距离这里是不是超过 n 个了

    如果是的话,取最小值?

    其实直接输出答案就行了,证明看这里


     代码:

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cstdio>
    using namespace std;
      
    const int MAX_N = 2000001;
      
    int n, m, max_val;
    int pre_sum[MAX_N], bgn[1000001];
    int f[1000001];
      
    inline int rd() {
        register int x = 0, c = getchar();
        while (!isdigit(c)) c = getchar();
        while (isdigit(c)) {
            x = x * 10 + (c ^ 48);
            c = getchar();
        }
        return x;
    }
      
    int main() {
        n = rd(); m = rd();
        register int v1, v2, v3, v4;
        for (int i = 1; i + 3 <= n; i += 4) {
            pre_sum[i] = pre_sum[i - 1] + (v1 = rd());
            pre_sum[i + 1] = pre_sum[i] + (v2 = rd());
            pre_sum[i + 2] = pre_sum[i + 1] + (v3 = rd());
            pre_sum[i + 3] = pre_sum[i + 2] + (v4 = rd());
            max_val = max(max_val, max(v1, max(v2, max(v3, v4))));
        }
        for (int i = ((n >> 2) << 2) + 1; i <= n; ++i) {
            pre_sum[i] = pre_sum[i - 1] + (v1 = rd());
            max_val = max(max_val, v1);
        }
        int maxi = (n << 1);
        for (int i = n + 1; i <= maxi; ++i)
            pre_sum[i] = pre_sum[i - 1] - pre_sum[i - n - 1] + pre_sum[i - n];
        int d, lef;
        while (m--) {
            d = rd(); lef = 1;
            if (max_val > d) {
                puts("NIE");
                continue;
            }
            for (int i = n + 1; i <= maxi; ++i) {
                while (pre_sum[i] - pre_sum[lef] > d) ++lef;
                if (lef > n) {
                    f[i - n] = f[lef - n] + 1;
                    bgn[i - n] = bgn[lef - n];
                } else {
                    f[i - n] = 1;
                    bgn[i - n] = lef;
                }
                if (i - bgn[i - n] >= n) {
                    printf("%d
    ", f[i - n]);
                    break;
                }
            }
        }
        return 0;
    }    
    

      

  • 相关阅读:
    Learning to Compare: Relation Network for Few-Shot Learning 论文笔记
    修改python import模块中的变量
    roslaunch保存的log文件没有打印的ERROR信息
    python json demo
    vscode 1.32.x按下鼠标左键无法拖曳选择,而旧一点的版本1.30.2可以
    java-ee--------jdbc
    集合
    关键字
    java面向对象
    数组
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9894054.html
Copyright © 2020-2023  润新知