zoukankan      html  css  js  c++  java
  • Codeforces 983B. XOR-pyramid【区间DP】

    LINK

    定义了一种函数f

    对于一个数组b

    当长度是1的时候是本身

    否则是用一个新的数组(长度是原数组-1)来记录相邻数的异或,对这个数组求函数f

    大概是这样的:

    (f(b[1]⊕b[2],b[2]⊕b[3],…,b[m−1]⊕b[m]))

    然后q次询问每次问一个区间的子区间里面最大的连续段的f函数值是多少


    思路

    首先考虑怎么快速计算f的函数值

    因为我们发现一个([l,r])的数组,考虑他最后状态的前一个状态

    这个时候只有两个元素,而这两个元素实际上就是([l,r-1])([l +1,r])着两个区间的函数值

    然后就把他们异或起来就可以了

    最后再区间DP一下算每个区间的子区间内最大的

    (O(1))回答询问


    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5010;
    int n, q, a[N];
    int f[N][N], g[N][N];
    
    void dp1() {
      for (int i = 1; i <= n; i++) f[i][i] = a[i];
      for (int len = 2; len <= n; len++) {
        for (int l = 1; l + len - 1 <= n; l++) {
          int r = l + len - 1;
          f[l][r] = f[l][r - 1] ^ f[l + 1][r];
        }
      }
    }
    
    void dp2() {
      for (int len = 1; len <= n; len++) {
        for (int l = 1; l + len - 1 <= n; l++) {
          int r = l + len - 1;
          g[l][r] = max(max(g[l][r - 1], g[l + 1][r]), f[l][r]);
        }
      }
    }
    
    int main() {
      scanf("%d", &n);
      for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
      dp1();
      dp2();
      scanf("%d", &q);
      while (q--) {
        int l, r;
        scanf("%d %d", &l, &r);
        printf("%d
    ", g[l][r]);
      }
      return 0;
    }
    
  • 相关阅读:
    c 概念详解
    c 目录
    win文件操作
    使用panads处理数据
    冒泡排序
    notepad++搭建python环境
    继承方法-->一级一级继承
    原型问题2—原型对象的替换
    原型问题1—原型对象的替换
    js继承——扩展Object方式实现继承
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9917921.html
Copyright © 2011-2022 走看看