zoukankan      html  css  js  c++  java
  • Codeforces每日一练 533E+235A+533B

    533E Correcting Mistakes

    传送门
    镜像传送门
    字符串+思维
    给你两个不同的字符串,向每个字符串里加一个字母使得两个字符串一致,问可能的加入方法有多少种。
    (为啥tag里会有dp~~~)
    先把两端一样的部分删去,留下中间的的部分(想起了昨晚的D题QAQ),根据之前删除的方法,可以确定两个字符串中间部分两端的字母一定不相同,那么我们在加字母的时候只能在两端加,因为加在中间并不影响两端是否匹配,那么答案最多有两种,我们可以选择第一个加在前面第二个加在后面或者相反的方法,对于第一种方法,如果第一个字符串1—len-1和第二个字符串2—len是相同的,那么该方法就成立,同理我们可以判断第二种方法,都成立输出2,成立一个输出1,否则输出0.

    signed main()
    {
        ios ; cin.tie(0) , cout.tie(0);
        int n;
        cin>>n;
        string s,t;
        cin>>s;
        cin>>t;
        set<int> pos;
        int l=-1,r=-1;
        for (int i = 0; i <n ; ++i) {
            if(s[i]!=t[i]){
                pos.insert(i);
            }
        }
        if(pos.size()==1){cout<<2;return 0;}
        l=*pos.begin();
        auto m=pos.end();
        m--;
        r=*m;
        string s1,s2,t1,t2;
        for (int j = l+1; j <=r ; ++j) {
            s1+=s[j];
            s2+=s[j-1];
            t1+=t[j-1];
            t2+=t[j];
        }
        if(s1==t1||s2==t2){
            if(s1==t1&&s2==t2)cout<<2;
            else cout<<1;
        }
        else cout<<0;
        return 0;
    }
    

    235A LCM Challenge

    传送门
    镜像传送门
    数论
    在小于等于n的数里找三个数(可以相同)使他们的最小公倍数最大。
    1/2肯定要特判,对于>2的,当n为奇数时,显然答案是n*(n-1)(n-2),三者必定互质,因为不互质奇数的gcd最大为3,那么两者的差肯定大于等于3,而n和n-2相差2,偶数和奇数不互质,差同样大于等于3。三者的积即为当前答案。如果n为偶数,只需要在几个选择里挑选即可,第一种为n×(n-1)×(n-2)/2,如果选n-2之后的偶数肯定是没有n-2优的,第二种为(n-1)×(n-2)×(n-3),即再构造一个相邻的奇偶奇,第三种为n×(n-1)×(n-3)/gcd(n,n-3),即继续向后找一个奇数,对于后面的奇数,肯定没有当前优,因为后面的奇数n小于n^2-5n<第二种里的(n-2)×(n-3)。
    代码

    signed main()
    {
        ios ; cin.tie(0) , cout.tie(0);
        ll n;
        cin>>n;
        ll a=n,b=n-1,c=n-2;
        if(n==1)cout<<1;
        else if(n==2)cout<<2;
        else {
            if(n%2)cout<<a*b*c;
            else{
                ll ans=max(n*(n-1)*(n-2)/2,(n-2)*(n-1)*(n-3));
                ans=max(ans,n*(n-1)*(n-3)/gcd(n,n-3));
                cout<<ans;
            }
        }
        return 0;
    }
    

    533B Work Group

    传送门
    镜像传送门
    公司里总裁编号是1,其他人编号2-n,每个人有自己的直接上司和自己的工作效率值,现在选择一部分人,使得小组里每个人都有偶数个下属,并且使这些人的工作效率和最大。
    很明显是一道树形dp,问题在于怎么样转移方程。对于以每个节点为根的子树,有两种情况,取奇数个下属或者取偶数个下属(分别以1/0表示),可以考虑开个二维数组分别存奇数和偶数的情况,对于每个结点x,依次考虑以他的直接下属为根的子树,显然dp[x][0]=max(dp[x][1]+dp[i][1],dp[x][0]+dp[i][0]),dp[x][1]同理,因为我们是依次加入子树,所以并不会互相影响,但要注意每个结点的dp[x][1]要初始化为极小值,防止第一次转移时dp[x][0]=dp[i][1]。考虑完所有直接下属,回到当前节点,dp[x][1]有两种情况,不取当前结点取奇数个,取当前结点然后取偶数个,二者取最大值即可。
    对于最后的答案,显然是dp[1][0]+a[1]和dp[1][1]的最大值,不取1,其余节点必取奇数个(否则没有取1优),或者取1,其余节点取偶数个,而在dfs里我们已经处理过二者的最大值,直接输出dp[1][1]即可。

    int n;
    #define maxn 200005
    vector<int> g[maxn];
    int a[maxn],dp[maxn][2];
    void calc(int x,int fa){
        dp[x][0]=0;
        dp[x][1]=-100000000;
        for(auto i:g[x]){
            if(i!=fa){
                calc(i,x);
                int l=dp[x][0],r=dp[x][1];
                dp[x][0]=max(l+dp[i][0],r+dp[i][1]);
                dp[x][1]=max(r+dp[i][0],dp[i][1]+l);
            }
        }
        if(g[x].empty()){
            dp[x][0]=0;
            dp[x][1]=a[x];
        }
        dp[x][1]=max(dp[x][0]+a[x],dp[x][1]);
    }
    signed main()
    {
        ios ; cin.tie(0) , cout.tie(0);
        cin>>n;
        rep(i,1,n){
            int p;
            cin>>p>>a[i];
            if(p!=-1)g[p].push_back(i);
        }
        calc(1,-1);
        cout<<dp[1][1];
        return 0;
    }
    

    (ps:数论题讲起来真麻烦QAQ

  • 相关阅读:
    javascript的语法作用域你真的懂了吗
    网页的三种布局(固定宽度式,流体式,弹性式)
    css3系列之animation
    跟我学习css3之transition
    函数调用你知道几种方法
    javascript的那些事儿你都懂了吗
    css3的那些高级选择器二
    [转]影响Cache的几个HTTP头信息
    CSS属性合写
    defer 与 async
  • 原文地址:https://www.cnblogs.com/Bazoka13/p/12623393.html
Copyright © 2011-2022 走看看