首页 > 其他分享 >Codeforces Round 804 (Div. 2)(C - D)

Codeforces Round 804 (Div. 2)(C - D)

时间:2024-10-09 20:45:13浏览次数:1  
标签:int text Codeforces long solve mp Div dp 804

C

C
观察题意, 模拟样例, 首先 \(0\) 不能动, 因为相邻的 \(mex\) 会改变, 然后 \(1\) 也是如此, 所以我们固定了 \(0\) 和 \(1\), 设两个指针 \(l\) 和 \(r\) 表示固定的位置, 那么此时在他们两个中间的数可以随便移动, 假设有 \(x\) 个空位, 那么如果 \(2\) 在里面, \(2\) 的选择则是 \(x\) 个, 如果不在, 那么很明显我们不能把 \(2\) 放进去, 接着我们固定 \(1\) 和 \(2\), 现在可用的空位为 \(r - l - (i + 1)\), 如果 \(3\) 在这个空位里面, 那么同理, 会有 \(r - l - 1 - i\) 随便选择, 这里的 \(i + 1\) 指的是已经固定了的位置, 依次类推即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10, mod = 1e9 + 7;
void solve(){

    int n; cin >> n;
    
    map<int, int> mp;
    vector<int> a(n + 1);
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        mp[a[i]] = i;
    }

    int l = mp[0], r = mp[0], res = 1;
    for(int i = 1; i < n; i++){
        int x = mp[i];
        if(x < l) l = x;
        else if(x > r) r = x;
        else res = res * (r - l + 1 - i) % mod;
    }

    cout << res << '\n';
}
signed main(){
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t;cin>>t;while(t--)solve();
}

D

D
最优方案题, 我们要考虑贪心或者 \(dp\) 或者图论
贪心明显不可以, 因为我们无法保证当前操作不会影响前面的操作, 并且难以维护
考虑\(dp\), 设 \(dp_i\) 为 \(a_i\) 在 \(i\) 位置最多能保留多少个
下面给出一个函数 \(deletable\), 定义如下:

  • 一个区间 \([l,r]\) 若可删除, 则有 \(deletble [l,r]\)
  • 区间必须是偶数长度
  • 若区间 \([l,r]\) 内的众数不大于区间长度的一半则可以完全删除

那么 \(dp_i\) 是由 \(dp_{j∈(0, i - 1)}\) 转移而来, 需要满足:

\[dp_i = \max_{j=0}^{i-1} \left( \text{Deletable}(j+1, r) \land (a_i = a_j \mid j=0) \right) \cdot (dp_j + 1) \]

由于我们的 \(dp_i\) 表示的是前 \(i\) 个, 所以我们 \(i → n\) 是不要了的, 也需要满足 \(Deletabele[i + 1, n]\), 那么答案就是:

\[ \text{ans} = \max_{i=1}^{n} \text{Deletable}(i+1, n) \cdot dp_i \]

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10, mod = 1e9 + 7;
int cnt = 0;
void solve(){

    int n; cin >> n;
    
    vector<int> a(n + 1);
    vector<vector<int>> sum(n + 1, a);
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        for(int j = 1; j <= n; j++){
            sum[i][j] = sum[i - 1][j];
        }
        sum[i][a[i]]++;
    }

    vector<int> f(n + 1), g(n + 1);
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            g[i] = max(g[i], sum[n][j] - sum[i][j]);
        }
    }

    int res = 0;
    vector<int> dp(n + 1, -1e9);
    dp[0] = 0;
    for(int i = 1; i <= n; i++){
        int tot = 0;
        for(int j = i - 1; j >= 0; j--){
            int l = j + 1, r = i - 1;
            tot = max(tot, sum[r][a[l]] - sum[l - 1][a[l]]);
            if((r - l + 1) % 2 == 0 && tot <= (r - l + 1) / 2 && (j == 0 || a[i] == a[j])){
                dp[i] = max(dp[i], dp[j] + 1);
            } 
        }

        if((n - i) % 2 == 0 && g[i] <= (n - i) / 2){
            res = max(res, dp[i]);
        }        
    }   

    cout << res << '\n';

}
signed main(){
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t;cin>>t;while(t--)solve();
}

标签:int,text,Codeforces,long,solve,mp,Div,dp,804
From: https://www.cnblogs.com/o-Sakurajimamai-o/p/18455093

相关文章

  • [AGC064C] Erase and Divide Game 题解
    DescriptionTakahashi和Aoki玩游戏。先在黑板上写若干个数,由\(N\)个互不相交的区间\([l_i,r_i]\)组成。两人轮流操作,每次操作先删去所有的奇数/偶数,再把剩下的数除以\(2\)(向下取整),无法操作的人输。Takahashi先手,假设两人都采用最优策略,问谁能获胜。\(1\leqN\leq10^......
  • Codeforces Round 970 (Div. 3) D. Sakurako‘s Hobby
     链接cf_Sakurako‘sHobby大意:给一堆点和边,并给出点的颜色,输出每个点能遍历到几个黑点思路:1、这些点边里面有拓扑结构,也有环2、先处理拓扑排序的一些点,依次遍历无父节点的即可,之后就会剩下环3、有环的说明每个点都能去到环内任意一点,那么直接就记录一个sum,然后递归......
  • Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)
    目录写在前面A签到B贪心,枚举C1贪心C2贪心,枚举DDPE1/E2Kruscal重构树,树上背包写在最后写在前面补题地址:https://codeforces.com/contest/2021。上大分失败呃呃呃呃我不要上班呜呜A签到考虑仅有三个数\(a,b,c(a<b<c)\)时最优操作,手玩下发现最优操作顺序一定是......
  • divide by zero encountered in log10 my_vmin=np.log10(data['PValue'].min())
     sm=plt.cm.ScalarMappable(cmap='viridis',norm=plt.Normalize(vmin=np.log10(data['PValue'].min()),vmax=np.log10(data['PValue'].max()))) C:\Python310\lib\site-packages\pandas\core\arraylike.py:397:RuntimeWarning:d......
  • Codeforces Round 316 (Div. 2) D题 Tree Requests(二分,dfs,在线,前缀异或)
    题目链接CodeforcesRound316(Div.2)D题TreeRequests思路将262626个字母全部当作一个二进制数。将每个深度的结点按照dfs序放到一个vector里,同时记录每个vector......
  • 【前缀和+开区间二分】codeforces 1187 B. Letters Shop
    题意第一行,输入一个正整数\(n(1\leqn\leq2*10^5)\),代表字符串\(s\)的长度。第二行,输入一个字符串\(s\)。第三行,输入一个正整数\(m(1\leqm\leq5*10^4)\),代表接下来要输入的询问次数,对于每次询问:输入一个字符串\(t(1\leq|t|\leq2*10^5)\),并保证\(\sum_{i=1}^m......
  • Codeforces Round 969 (Div. 2)
    一万五参赛,赛时(VP)排名80A.Dora'sSet比较新的结论题。显然,一个合法三元组最多只能有一个偶数。每个偶数都可以跟相邻两个奇数组成合法三元组。因此,答案为奇数个数的二分之一(下取整)。#include<bits/stdc++.h>usingnamespacestd;intT,l,r;intmain(){ scanf("%d",......
  • Codeforces Round 977 (Div. 2)
    手速局,因为水平不够三题遗憾离场。A.MeaningMean题意你一个序列,你每次可以选择两个数删掉,并把他们的平均数加入到序列的末尾。当序列长度为\(1\)的时候,剩下的数最大值是多少。思路当时比赛的时候唐了,耽误了好几分钟。想的是先奇数和奇数相加,偶数和偶数相加,这样能避免下取......
  • Codeforces Rund 977 div2 个人题解(A~E1)
    CodeforcesRund977div2个人题解(A,B,C1,C2,E1)Dashboard-CodeforcesRound977(Div.2,basedonCOMPFEST16-FinalRound)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#includ......
  • Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)
    CodeforcesRound977(Div.2,basedonCOMPFEST16-FinalRound)A.MeaningMean题目链接:Problem-A-Codeforces题目描述:给定一个包含(n)个正整数的数组(a)。你可以执行如下操作直到数组中只剩下一个元素:从数组中选择两个不同的元素(a_i)和(a_j......