• 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 
    #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;
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    C. Customs Controls 2

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

    #include 
    #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;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
  • 相关阅读:
    01 - Apache Seatunnel 源码调试
    Linux学习-21-yum命令(查询、安装、升级和卸载软件包)和软件组管理
    MyBatis简述
    find命令-随心所欲查找服务器的文件
    [部署网站02]下载安装 unix PHP7.4 Swoole Loader扩展文件
    数据可视化之大数据平台可视化
    数据库持久化+JDBC数据库连接
    播放器事件/与JS交互
    Tomcat多实例 + Tomcat负载均衡、动静分离(Nginx联动)
    05.JavaScript(防抖节流、视频播放定位上次位置)
  • 原文地址:https://blog.csdn.net/weixin_51934288/article/details/127972603