• 题解 CF813D


    1. CF813D

    题意:

    给一个长度为(n)的序列,求两个不相交的子集长度之和最大是多少,能放入同一子集的条件是首先顺序不能变,然后每一个相邻的要么相差(1)或者相差(7)的倍数。 (n < 5000)

    题解:

    (f[i][j]) 表示第一序列到了第 (i) 位,第二个序列到了第 (j) 位,符合条件的长度之和最大.

    那么显然可以退出 (O(n^3)) 方程:

    i : 1 ~ n
    j : i + 1 ~ n
    k : 分两段。
    第一段:1 ~ i,此时判一下a[k]有没有被j选中,如果没有在考虑转移i
    第二段:j ~ n,此时就分别转移i,j就行了
    

    那么这肯定是过不了的,所以还需要优化。

    就是开一个桶记录相差 (1)(max)

    再开一个桶记录 (\%7) 同余

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #define N 5200
    #define M 100010
    #define ls x << 1
    #define rs x << 1 | 1
    #define inf 10000000000
    #define inc(i) (++ (i))
    #define dec(i) (-- (i))
    // #define mid ((l + r) >> 1)
    #define int long long
    #define XRZ 212370440130137957
    #define debug() puts("XRZ TXDY");
    #define mem(i, x) memset(i, x, sizeof(i));
    #define Next(i, u) for(register int i = head[u]; i ; i = e[i].nxt)
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout);
    #define Rep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i <= i##Limit ; inc(i))
    #define Dep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i >= i##Limit ; dec(i))
    int dx[10] = {1, -1, 0, 0};
    int dy[10] = {0, 0, 1, -1};
    using namespace std;
    // const int base = 30;
    // const int prime = 19260817;
    inline int read() {
        register int x = 0, f = 1; register char c = getchar();
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
        return x * f;
    }
    int pre[M], num[10], n, ans, a[N], f[N][N];
    void clean() { mem(num, 0) mem(pre, 0)}
    signed main() { n = read();
        Rep(i, 1, n) a[i] = read();
        Rep(i, 0, n) { clean();
            Rep(j, 1, i - 1) pre[a[j]] = max(pre[a[j]], f[i][j]), num[a[j] % 7] = max(num[a[j] % 7], f[i][j]);
            Rep(j, i + 1, n) { f[i][j] = f[i][0] + 1;
                f[i][j] = max(f[i][j], max(pre[a[j] + 1] + 1, max(pre[a[j] - 1] + 1, num[a[j] % 7] + 1))); f[j][i] = f[i][j];
                pre[a[j]] = max(pre[a[j]], f[i][j]), num[a[j] % 7] = max(num[a[j] % 7], f[i][j]); ans = max(ans, f[i][j]);
            }
        }
        printf("%lld", ans);
    	return 0;//int zmy = 666666, zzz = 233333;
    }
    
  • 相关阅读:
    010_STM32CubeMXADC
    009_STM32CubeMXPWM
    008_STM32CubeMX定时器中断
    007_STM32CubeMX外部中断
    006_STM32CubeMX按键输入
    005_STM32CubeMX串口
    004_STM32CubeMX官方例程
    003_STM32CubeMX点灯
    002_STM32CubeMX配置基础工程
    006_word发表博客到博客园中
  • 原文地址:https://www.cnblogs.com/Flash-plus/p/13834292.html
Copyright © 2020-2023  润新知