首页 > 其他分享 >NOIP

NOIP

时间:2024-11-05 13:30:12浏览次数:1  
标签:ch NOIP int Max void else include

noip 考前专训

(来自弱省弱校的挣扎)

T1 专训

38 题,在一个小时内写出正解。

P11186 三目运算

体现出我不会递归的牛逼情况。

照着题目模拟,类似对一段区间进行染色。

因为递归成一颗二叉树形状,故从最深处返回的下标为紧挨下一次递归开始的下标。

点击查看代码
#ifdef ONLINE_JUDGE
#else
#define FRZ_29
#endif

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
typedef long long LL;

using namespace std;

void RD() {}
template<typename T, typename... U> void RD(T &x, U&... arg) {
    x = 0; int f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f; RD(arg...);
}

void WT() {}
template<typename T> void WT(T &x) {
    if (x < 0) { putchar('-'); x = -x; }; 
    if (x > 9) WT(x / 10);
    putchar(x % 10 + '0');
}

const int N = 2e6 + 5;

#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

int m, q, ans[N / 10];
char s[N];

int gi(int pos, int &x) {
    x = 0;
    while (s[pos] >= '0' && s[pos] <= '9') {
        x = x * 10 + (s[pos] ^ '0'); pos++;
    }
    return pos;
}
int dfs(int pos, int l, int r) {
    if (s[pos] >= '0' && s[pos] <= '9') {
        int t;
        int num = gi(pos, t);
       LF(i, l, r) ans[i] = t;
        return num;
    }
    int s1;
    int s2 = gi(pos + 2, s1);
    if (s[pos + 1] == '>') {
        int nx = dfs(s2 + 1, s1 + 1, r);
        return dfs(nx + 1, l, s1);
    } else {
        int nx = dfs(s2 + 1, l, s1 - 1);
        return dfs(nx + 1, s1, r);
    }
}
int main()
{
#ifdef FRZ_29
    freopen("z_example.in", "r", stdin);
    freopen("z_example.out", "w", stdout);
#endif
    RD(m, q); cin >> s;
    dfs(0, 1, m + 1);
    while (q--) {
        int x; RD(x);
        printf("%d\n", ans[min(x, m + 1)]);
    }
    return 0;
}

// START:2024/11/01 21:25:21;

耗时约 45min,体现出我不会递归的牛逼状况。

P11187 配对序列

简单动态规划。

首先写了 \(O(n^2)\) 的暴力验证想法,像维护最长上升子序列那样。

设 \(f_{i, 0}\) 表示以 \(i\) 为结尾的子序列结尾两字符相等的最长长度,\(f_{i, 1}\) 表示以 \(i\) 结尾的子序列结尾两字符不相等的最长长度。

显然:

\[f_{i, 0} = \max_{j \in [1, i), a_i = a_j}(f_{j, 1} + 1, f_{i, 0}) \]

\[f_{i, 1} = \max_{j \in [1, j), a_i \not= a_j}(f_{j, 0} + 1, f_{i, 1}) \]

\(f_{i, 0}\) 的转移可以记录 \(a_i\) 上一次出现的位置,因为决策区间单调。

\(f_{i, 1}\) 的转移可以记录前缀最大值和次大值,因为要避免重复。

点击查看代码
#ifdef ONLINE_JUDGE
#else
#define FRZ_29
#endif

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
typedef long long LL;

using namespace std;

void read() {}
template<typename T, typename... U> void read(T &x, U&... arg) {
    x = 0; int f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f; read(arg...);
}

void write() {}
template<typename T> void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }; 
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

const int N = 5e5 + 5;

#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

int n, a[N], lst[N];
int f[N][2];

int main() {
#ifdef FRZ_29
    freopen("z_example.in", "r", stdin);
    freopen("z_example.out", "w", stdout);
#endif

    read(n); 
    LF(i, 1, n) read(a[i]);
    LF(i, 1, n) f[i][1] = 1;
    pair<int, int> Max[2] = {{0, 0}, {0, 0}};
    LF(i, 1, n) {
        if (Max[0].second == a[i]) f[i][1] = max(f[i][1], f[i][1] + Max[1].first);
        else f[i][1] = max(f[i][1], f[i][1] + Max[0].first);

        if (!lst[a[i]]) { lst[a[i]] = i; continue; }
        f[i][0] = max(f[i][0], f[lst[a[i]]][1] + 1);
        lst[a[i]] = i; 
        if (f[i][0] > Max[0].first) {
            if (Max[0].second == a[i]) { Max[0].first = f[i][0]; continue; }
            else {
                Max[1] = Max[0];
                Max[0] = { f[i][0], a[i] };
            }
        } else if (f[i][0] > Max[1].first){
            if (Max[0].second == a[i]) continue;
            Max[1] = { f[i][0], a[i] };
        }
    }

    int ans = 0;
    LF(i, 1, n) ans = max(ans, f[i][0]);
    // LF(i, 1, n) printf("f[%d]: 0 %d 1 %d\n", i, f[i][0], f[i][1]);
    write(ans);
    return 0;
}

// START:2024/11/02 13:04:05;

耗时 30min,还行。

标签:ch,NOIP,int,Max,void,else,include
From: https://www.cnblogs.com/FRZ29/p/18527685

相关文章

  • P1088 [NOIP2004 普及组] 火星人
    [NOIP2004普及组]火星人题目描述人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小......
  • NOIP 历年题集
    2015D1T1神奇的幻方简单模拟。代码D1T2信息传递可以发现,我们要求的即为该有向图的最小环,观察该图,是一个内向基环树,我们可以直接dfs找环即可。代码D1T3斗地主好像是个爆搜剪枝?不想写。D2T1跳石头显然可以二分一个\(mid\),然后我们贪心的选择删除距离小于\(mi......
  • [NOIP 2023 模拟7]路程
    [NOIP2023模拟7]路程题意:给一个数字n:起点为1,终点为114这张图正好有n+1条从1到114的路径,并且在这些路径的边权和中,[0,n]的每一个整数正好出现了一次。问:给出一种可能的建图方法----约束:边数<=45,点数<=18(包含1和114)思路:一.考场做法:考虑将(n+1)分解质因数,(n+1)可能为素......
  • NOIP2024模拟1
    rank6,T159,T250,T350,T40打了三道搜索。T4树套树没调出来就结束了香雪还没写,遗憾离场。玩游戏贪心,只会暴力跳……点此查看代码#include<bits/stdc++.h>usingnamespacestd;#definerep(i,s,t,p)for(inti=s;i<=t;i+=p)#definedrep(i,s,t,p)for(inti=s;i......
  • 拓扑AC NOIP模拟赛1
    题出的不错,但是测试时限与下发时限不同,怎么会是呢?T1题目链接先考虑弱化版。对于答案,一定有其中一个位置的高度被用满。所以枚举这个位置,在考虑这个位置被占满时的最大答案。发现只需要找出这个位置之前第一个\(<\)它的高度的位置和它之后第一个\(<\)它的高度的位置即可......
  • 「模拟赛」NOIP2024 模拟 1
    A.玩游戏贪心贪心假做法A了,左指针从一直向左移,右指针暴跳到最远的位置被hack了,没关系,特判一下......
  • [赛记] 多校A层冲刺NOIP2024模拟赛16 && 17
    四舍五入100pts对于一个数$x$,可以发现它的答案可以分成两部分,一部分在$[2x+1,n]$范围内,一部分在小于它的数的范围内,前者$\Theta(1)$算,对于后者,我们发现满足这个要求的数$y$一定有$x\mody<w(x,y)$($w(x,y)$定义为如果$x\mody=0$,则$w(a,......
  • 「NOIP2022」建造军营 题解
    前言题目链接:洛谷。题意简述yzh送你一张\(n\)个点\(m\)条边的无向连通图,你可以决定选择\(n\)个点中若干个、\(m\)条边中若干条,方案数为\(2^n2^m\)。在你操作后,yzh会任意挑选一条边,如果这条边没有被你选中,那么就要断开这条边,否则什么事也没发生。你需要保证无论yzh......
  • NOIP2024模拟1
    NOIP2024模拟1\(T1\)HZTG2080.玩游戏\(24pts\)强化版:HDU6326ProblemH.MonsterHunter部分分\(24pts\):\(O(n^{2})\)枚举所有可能的状态进行转移。点击查看代码lla[100010],sum[100010],f[2][100010];intmain(){ llt,n,k,i,j,len,l,r; cin>>t; for(......
  • 『模拟赛』NOIP2024模拟1
    Rank有点可惜,A.玩游戏绝妙贪心题。感觉这种能产生很多假做法且都可hack的贪心都是好题。赛时不知道为什么犯唐没交一开始的暴力贪心。考虑双指针,设左右指针分别为\(l,r\)。主要思路是实时维护当前两个指针向两边最近的一个区间和不为正的段,记录该区间的和\(sum1/sum2......