2022CCPC绵阳站A+广东站C

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022CCPC绵阳站A+广东站C相关的知识,希望对你有一定的参考价值。

最后几天了,虽然一堆考试没复习,压力山大,不过都是小事。
这几次的vp我们发挥的还可以,稳铜了。
希望我们队在济南也能有一个好的结果,不留遗憾。

A. Ban or Pick, What’s the Trick

记忆化搜索,好久没做了。当时vp时写了个贪心,wa6了,就想到可能是dp了。
思路:
1.看到k的范围只有10,设计状态dp[round][numa][numb]:在已经进行i轮的基础上,A选了numa个英雄,B选了numb个英雄时的分数。
2.结束状态:当进行到n*2轮的时候,递归返回。
3.状态转移:由于从0开始累计操作,因此偶数轮A行动,奇数轮B行动。一个小的注意点,当A行动完,B行动的时候,需要通过(轮数+1)/2才是A行动的轮数。
4.每个人行动时,都有两种情况。选择己方英雄或ban掉对方英雄。
选择己方:res=max(res,dfs(round+1,numa+1,numb)+a[ra+1])
ban对方:res=max(res,dfs(round+1,numa,numb))此处轮数+1,但A的英雄数并没增加
5.A希望最大化分数,因此取max;B希望最小化分数,因此减去己方英雄值时候取min。

#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))

using namespace std;
const int N =2e5+5;
const int inf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
int n,k,a[N],b[N],dp[N][15][15];
int dfs(int round,int numa,int numb)

    if(round==2*n)
        return 0;
    if(dp[round][numa][numb]!=-inf)
        return dp[round][numa][numb];
    int ra=round/2-numb+numa;
    int rb=(round+1)/2-numa+numb;
    if(round%2==0)
    
        int res=-inf;
        if(numa<k&&ra<n)
            res=max(res,dfs(round+1,numa+1,numb)+a[ra+1]);
        res=max(res,dfs(round+1,numa,numb));
        return dp[round][numa][numb]=res;
    
    else
    
        int res=inf;
        if(numb<k&&rb<n)
            res=min(res,dfs(round+1,numa,numb+1)-b[rb+1]);
        res=min(res,dfs(round+1,numa,numb));
        return dp[round][numa][numb]=res;
    

void solve()

    memset(dp,-inf,sizeof dp);
    cin>>n>>k;
    for(int i=0;i<=2*n;i++)
        for(int j=0;j<=k;j++) for(int s=0;s<=k;s++) dp[i][j][s]=-inf;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    sort(a+1,a+n+1,greater<int>());
    sort(b+1,b+n+1,greater<int>());
    cout<<dfs(0,0,0)<<endl;

signed main()

    ios;
    solve();
    return 0;




C. Customs Controls 2

1.各个点到点t的距离相同,需要从终点反向遍历,合并点集。
2.正向存边,处理得到每一个结点的度。
3.进行拓扑遍历合并后的DAG图,dp[u]表示从点1出发的路径长度。

#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
#define re register
using namespace std;
const int N =7e5+5;
const int inf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
int n,m,f[N],dp[N],d[N];
vector<int>e[N],g[N];
vector<PII>mp;
int r_find(int r)

    if(f[r]==r) return f[r];
    f[r]=r_find(f[r]);
    return f[r];

void solve()

    cin>>n>>m;
    mp.clear();
    for(int i=0;i<=n;i++) f[i]=i,dp[i]=d[i]=0,e[i].clear(),g[i].clear();
    for(int i=1;i<=m;i++)
    
        int x,y;cin>>x>>y;
        e[y].push_back(x);
        mp.push_back(x,y);
    
    for(int i=1;i<=n;i++)
    
        for(int v:e[i])
            f[r_find(v)]=r_find(e[i][0]);
    
    for(auto cur:mp)
    
        int x=cur.first,y=cur.second;
        g[r_find(x)].push_back(r_find(y));
        d[r_find(y)]++;
    
    int cnt=0;
    queue<int>q;
    for(int i=1;i<=n;i++)
    
        if(f[i]==i)
        
            cnt++;
            if(d[i]==0)
                dp[i]=1,q.push(i);
        
    
    while(!q.empty())
    
        int u=q.front();q.pop();
        cnt--;
        for(int v:g[u])
        
            dp[v]=max(dp[u]+1,dp[v]);
            d[v]--;
            if(!d[v]) q.push(v);
        
    
    if(cnt) cout<<"No"<<endl;
    else
    
        cout<<"Yes"<<endl;
        for(int i=1;i<=n;i++)
        
            int ans=dp[r_find(i)];
            if(i!=1) ans-=dp[r_find(e[i][0])];
            cout<<ans<<" ";
        
        cout<<endl;
    

signed main()

    ios;
    int T;
    cin>>T;
    while(T--)
        solve();
    return 0;



以上是关于2022CCPC绵阳站A+广东站C的主要内容,如果未能解决你的问题,请参考以下文章

2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题

2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题

2018CCPC秦皇岛站

秦皇岛站2019CCPC A.Angel Beats

2020CCPC绵阳

考试记录20180920