• Codeforces Round #627 (Div. 3)【ABCDEF】(题解)


    目录

    涵盖知识点:思维、dp、树形dp。

    比赛链接:传送门

    A - Yet Another Tetris Problem

    题意: 俄罗斯方块
    题解: 判断所有数的奇偶性
    Accept Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=110;
    int a[maxn];
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            for(int i=1;i<=n;i++){
                cin>>a[i];
            }
            bool flag=true;
            int base=a[1]&1;
            for(int i=2;i<=n;i++){
                if((a[i]&1)!=base){
                    flag=false;
                    break;
                }
            }
            puts(flag?"YES":"NO");
        }
        return 0;
    }
    

    B - Yet Another Palindrome Problem

    题意: 问能否找一个子序列,其为长度为3的回文串
    题解: 两个相同数中间还有任意的数字即可。
    Accept Code:写的有点丑。。。讲道理(n^2)扫一遍就完事了

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=5050;
    int a[maxn];
    vector<int> v[maxn];
    int main(){
        int t;
        cin>>t;
        while(t--){
            for(auto & i : v){
                i.clear();
            }
            int n;
            cin>>n;
            for(int i=1;i<=n;i++){
                cin>>a[i];
                v[a[i]].push_back(i);
            }
            bool flag=false;
            for(int i=1;i<maxn;i++){
                if(v[i].size()==0||v[i].size()==1)continue;
                if(v[i].size()>2){
                    flag=true;
                    break;
                }
                for(int j=1;j<v[i].size();j++){
                    if(v[i][j]-v[i][j-1]>1){
                        flag=true;
                        goto st;
                    }
                }
            }
            st:
            puts(flag?"YES":"NO");
        }
        return 0;
    }
    

    C - Frog Jumps

    题意: 一个蛤在第(i)块只能根据该块的指定方向跳([1,d]的距离)求最小的(d)使得蛤能从(0)跳到(n+1)
    题解: 找最长的连续L串。长度再加1就行了。证明自行脑补。
    Accept Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=5050;
    int a[maxn];
    int main(){
        int t;
        cin>>t;
        while(t--){
            string s;
            cin>>s;
            s='R'+s;
            int cnt=0,ans=0;
            for(char i:s){
                if(i=='L'){
                    cnt++;
                }
                else{
                    ans=max(ans,cnt);
                    cnt=0;
                }
            }
            ans=max(ans,cnt);
            cout<<ans+1<<"
    ";
        }
        return 0;
    }
    

    D - Pair of Topics

    题意: 问有多少对((i,j))使得(a_i+a_j>b_i+b_j)
    题解: 移项得到(a_i-b_i>b_j-a_j)。我们令(c_i=a_i-b_i),然后将其从大到小排序。双指针(i,j)分别从左右扫描。当(c_i>-c_j)时,对答案有(j-i)的贡献。当(ige j)时结束扫描即可。
    Accept Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn],b[maxn],c[maxn];
    typedef long long ll;
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=n;i++) {
            cin >> b[i];
            c[i]=a[i]-b[i];
        }
        sort(c+1,c+1+n,greater<int>());
        int pos=n;
        ll ans=0;
        for(int i=1;i<=n;i++){
            while (c[i]+c[pos]<=0&&pos>i)pos--;
            if(i>=pos)break;
            ans+=1ll*pos-i;
        }
        cout<<ans<<"
    ";
        return 0;
    }
    

    E - Sleeping Schedule

    题意: 现在一天(h)小时,总共要睡(n)次,一次睡一天,第(i)次 醒来之后可以选择(a_i)或者(a_i-1)个小时以后接着睡。如果醒来的时候在区间([l,r])内,我们认为睡眠是好的。问最多能睡几次好的。
    题解: (dp_{i,j})描述睡了(i)次醒来的时候是(j)的最优情况。初值:(dp_{0,0}=0,x=(j+a[i]-1)mod h,y=(j+a[i])mod h)
    转移方程:

    [egin{cases} dp_{i,x}=max(dp_{i-1,j}+[lle x le r])\ dp_{i,y}=max(dp_{i-1,j}+[lle y le r]) end{cases} ]

    所求值:(max(dp[n]))
    Accept Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2010,inf=0x3f3f3f3f;
    int dp[maxn][maxn],a[maxn];
    int n,h,l,r;
    bool check(int x){
        return x>=l&&x<=r;
    }
    int main(){
        cin>>n>>h>>l>>r;
        for (int i = 1; i <= n; i++) {
            cin>>a[i];
        }
        memset(dp,-inf,sizeof dp);
        dp[0][0]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<h;j++){
                int x=(j+a[i]-1)%h;
                dp[i][x]=max(dp[i][x],dp[i-1][j]+check(x));
                x++;
                x%=h;
                dp[i][x]=max(dp[i][x],dp[i-1][j]+check(x));
            }
        }
        int ans=0;
        for(int i=0;i<h;i++)
            ans=max(ans,dp[n][i]);
        cout<<ans<<"
    ";
        return 0;
    }
    

    F - Maximum White Subtree

    题意: 一棵无根树,有黑白两种点,问每个点的所有子树中白点数-黑点数的最大值。
    题解: 记黑点为-1,白点为1.默认以1号点为根(dfs)扫一遍,从叶子节点向根做一遍树形dp。
    转移方程:(dp_u=displaystylesum_{vin son_u}max(dp_v,0))
    再次(dfs)扫描一遍,在向下扫描的过程中,我们先假设断开(u,v)之间的连接,那么(ans_u=max(ans_u-max(dp_v,0),0)),那么(ans_v=dp_v+ans_u)。好像有点绕。。画个图脑补一下就好了。
    Accept Code:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn],ans[maxn],dp[maxn];
    vector<int> edg[maxn];
    void dfs1(int root,int fa){
        dp[root]=a[root];
        for(auto v:edg[root]){
            if(v==fa)continue;
            dfs1(v,root);
            dp[root]+=max(dp[v],0);
        }
    }
    void dfs2(int root,int fa,int res){
        ans[root]=dp[root]+res;
        for(auto v:edg[root]){
            if(v==fa)continue;
            dfs2(v,root,max(ans[root]-max(dp[v],0),0));
        }
    }
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(!a[i])a[i]=-1;
        }
        for(int i=1;i<=n-1;i++){
            int u,v;
            cin>>u>>v;
            edg[u].push_back(v);
            edg[v].push_back(u);
        }
        dfs1(1,0);
        dfs2(1,0,0);
        for(int i=1;i<=n;i++){
            cout<<ans[i]<<" ";
        }
        return 0;
    }
    
  • 相关阅读:
    Android Animations动画使用详解
    android LinearLayout和RelativeLayout实现精确布局
    中国天气网API
    获取中央气象台API 完整城市列表简单方式
    Django框架 连接Oracle -ServerName方式报错
    关于java的动态代理
    Mybatis缓存
    Git使用,将本地项目推送到GitHub上
    使用doxc4j将word转pdf遇到的一个问题
    linux安装jdk
  • 原文地址:https://www.cnblogs.com/charles1999/p/12485781.html
Copyright © 2020-2023  润新知