首页 > 其他分享 >Codeforces Round 972(Div.2)题解

Codeforces Round 972(Div.2)题解

时间:2024-09-23 16:24:13浏览次数:1  
标签:const int 题解 Codeforces vector DP Div.2 dp define

Codeforces Round 972(Div.2)题解

A. Simple Palindrome 贪心

贪心,尽可能元素数量平均,并且相同字母放在一起。

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 1;

void Showball(){
    int n;
    cin>>n;
    const string a="aeiou";
    int t=n/5;
    vector<int> cnt(5,t);
    for(int i=0;i<5;i++) if(i<n%5) cnt[i]++;
    for(int i=0;i<5;i++){
        while(cnt[i]--) cout<<a[i];
    }
    cout<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}

B2. The Strict Teacher (Hard Version) 二分+贪心

首先,答案只和 \(David\) 相邻的老师有关,因此二分一下找到相邻的老师,两端的情况,直接做差即可。

中间的情况,因为两个老师同时向中间逼近,显然答案就是距离差值的一半。

void Showball(){
    int n,m,q;
    cin>>n>>m>>q;
    vector<int> b(m);
    for(int i=0;i<m;i++) cin>>b[i];
    sort(all(b));
    while(q--){
        int x;
        cin>>x;
        auto p=lower_bound(all(b),x);
        if(p==b.end()){
            cout<<n-b[m-1]<<endl;
            continue;
        }
        if(p==b.begin()){
            cout<<b[0]-1<<endl;
            continue;
        }
        cout<<(*p-*(p-1))/2<<endl;
    }
}

C. Lazy Narek DP

首先考虑贪心,显然不行,因为两段字符串拼接到一起可以组成一段 \(narek\) 使得答案更优。

考虑 \(DP\), 为了和前面一段拼接,所以状态里要描述匹配到哪个字符。

不妨,我们令 \(DP_{i,j}\) 表示考虑到第 \(i\) 个字符串,匹配到第 \(j\) 个字符所获得的最大分数。

状态转移: \(DP_{i,j}=DP_{i-1,from} + calc()\)

\(calc()\) 用来计算这一段构成了多少个完整的串。

可以状态压缩,这里需要避免更新的新状态又去更新了别的状态,因此,我们可以复制一份dp数组。

每次记录好得分后,直接更新即可。最后的答案需要减去匹配到的字符数量 \(i\) ,因为那是 \(GPT\) 的得分。

void Showball(){
   int n,m;
   cin>>n>>m;
   vector<string> a(n);
   for(int i=0;i<n;i++) cin>>a[i];
 
   const string s="narek";
   vector<int> dp(5,-inf);
   dp[0]=0;
 
   for(int i=0;i<n;i++){
     auto ndp=dp;
     for(int j=0;j<5;j++){
      int k=j;
      int res=dp[j];
      for(auto c:a[i]){
        if(c==s[k]){
          k++;
          if(k==5){
            k=0;
            res+=5;
          }
        }else if(s.find(c)!=s.npos){
          res--;
        }
      }
      ndp[k]=max(ndp[k],res);
     }
     dp=ndp;
   }
   int ans=0;
   for(int i=0;i<5;i++) ans=max(ans,dp[i]-i);
   cout<<ans<<endl;
}

E1. Subtangle Game (Easy Version) 博弈+DP

不妨令 \(DP_{i,j,k}\) 表示第 \(i\) 步时选择 \(b_{j,k}\) 时是否可以必胜。

那么状态转移,我们倒着考虑,如果存在 \(s>j\) , \(t>k\) 且 \(DP_{i+1,s,t}=1\) 时,那么 \(DP_{i,j,k}\) 必败。

否则,如果 \(a_i=b_{j,k}\) 时,\(DP_{i,j,k}=1\)。对于上面这部分,我们可以用二位前缀和优化,因此 \(O(n^3)\)

可以通过该题。

void Showball(){
    int l,n,m; 
    cin>>l>>n>>m;
    vector<int> a(l+1);
    for(int i=1;i<=l;i++) cin>>a[i];
    vector<vector<int>> b(n+1,vector<int>(m+1));
    for(int i=1;i<=n;i++){
      for(int j=1;j<=m;j++){
        cin>>b[i][j];
      }
    }
 
    vector<vector<vector<int>>> dp(l+2,vector<vector<int>>(n+2,vector<int>(m+2)));
    for(int i=l;i;i--){
      for(int j=n;j;j--){
        for(int k=m;k;k--){
          if(b[j][k]==a[i]&&!dp[i+1][j+1][k+1]) dp[i][j][k]=1;
          dp[i][j][k]+=(dp[i][j+1][k]+dp[i][j][k+1]-dp[i][j+1][k+1]);
        }
      }
    } 
 
    if(dp[1][1][1]) cout<<"T\n";
    else cout<<"N\n"; 
}

标签:const,int,题解,Codeforces,vector,DP,Div.2,dp,define
From: https://www.cnblogs.com/showball/p/18427238

相关文章

  • Codeforces Round 973 (Div.2) A-E题解
    CodeforcesRound973(Div.2)A-E题解比赛传送门A.Zhan'sBlender数学显然答案为\(\lceil\frac{n}{min(x,y)}\rceil\)。#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.en......
  • 题解:AT_abc372_e [ABC372E] K-th Largest Connected Components
    题意给出\(q\)个操作。将\(u\)和\(v\)连边。问\(u\)所在的连通块中编号第\(k\)大的点。思路连通块很容易想到并查集,求第\(k\)大可以用平衡树(虽然赛时没看到\(k\le10\)),合并时将信息从将小的连通块合并到大的连通块,这样可以减少时间复杂度。什么?你不会写平衡......
  • 题解:AT_arc184_a [ARC184A] Appraiser
    题意\(1000\)个硬币中有\(10\)个假币,你每次可以询问两个位置的硬币类型是否相同,你需要用不超过\(950\)次询问找出所有假币的位置。思路将前\(990\)个硬币每\(11\)个分一组,共\(90\)组,余\(10\)个单独分一组。询问每组第\(1\)个硬币和这组后面硬币的关系。因为只......
  • CF1270H Number of Components 题解
    Description给一个长度为\(n\)的数组\(a\),\(a\)中的元素两两不同。对于每个数对\((i,j)(i<j)\),若\(a_i<a_j\),则让\(i\)向\(j\)连一条边。求图中连通块个数。支持\(q\)次修改数组某个位置的值,每次修改后输出图中连通块个数。\(n,q\le5\times10^5,1\lea_i\le10^......
  • 2024ICPC网络赛第二场题解(部分)
    前言这场相对作用大一点,最后顶着队友的怀疑压力乱搞出了C,但是后面看题解发现似乎是数据弱了跑过去,其实复杂度是队友分析的那样,是不正确的,但是毕竟是打名额的比赛,过了就是过了,这里分享一下C题的乱搞做法,以及其他题的我们队赛时代码。下面的顺序按过题顺序(也差不多是难度递增顺序)......
  • 网站程序打不开数据库错误等常见问题解决方法
    当遇到网站打不开或者数据库错误等问题时,可以按照以下步骤来诊断并解决问题:检查网站根目录:如果上传数据后显示“主机开设成功!”或“恭喜,lanmp安装成功!”,这通常是因为服务器默认放置了一个index.htm文件。此时应检查wwwroot目录内是否有自己的程序文件,并考虑删除默认的index.h......
  • 题解:AT_arc184_a [ARC184A] Appraiser
    本质上还是官方题解的分组并利用\(M\)不大的思路。询问次数\(Q\)离最简单的每个扫一遍就可以知道答案的做法少了\(50\)次。我们考虑如何减少这个次数。首先你可以发现一次询问可以覆盖到两个数,也就是说所有的数都被覆盖时只需要询问\(500\)次。我们考虑把不同的对拉出......
  • 网站打不开数据库错误等常见问题解决方法
    当遇到网站打不开且出现数据库错误等问题时,可以采取以下步骤进行排查和解决:检查默认页面:如果网站显示“主机开设成功!”或者“恭喜,lanmp安装成功!”这样的信息,这可能是服务器默认放置的页面。检查wwwroot目录下是否有自己的程序文件,如果没有,上传正确的文件,并删除默认的index.ht......
  • [ABC371F] Takahashi in Narrow Road 题解
    洛谷题目链接Atcoder题目链接前言这道题我赛时想到了正解并打了出来,然后因为把\(l\)打成了\(1\)导致WA\(\times23\),然后又没场切六道题(悲。然后赛后有人说正解是珂朵莉树/线段树,然而我是珂朵莉树\(+\)线段树,呵。题意数轴上有\(n\)个人,第\(i\)个人初始在\(X_i\)处,每一次操作......
  • codeforces 1041 C. Coffee Break
    题意第一行输入三个整数\(n,m,d(1\leqn\leq2*10^5,n\leqm\leq10^9,1\leqd\leqn)\),第二行输入\(n\)个整数,保证每个数均不大于\(m\)。在每一天你都可以任意选择一个未选过的数\(a_i\),随后可以继续选任意一个大于\(a_i+d\)的数\(a_j\);接下来可以再选任意......