• codeforces contest1082


    C 维护前缀和

    题意

    每一个id给一个权值序列,从每个id选出数量相同的权值,对他们进行求和,使得他们的和最大

    题解

    注意负数对结果没有贡献,直接跳过。

    当时写的比较挫,连排序都写错了!cf的编译器比较的严谨,虽然本地的编译器过了样例,但实际上是有问题的。结果就是交上去疯狂RE。

    题解就直接看代码,比较的直观

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    int n, m, k;
    int a[maxn];
    struct Node{
        int id, val;
        bool operator < (const Node &b) const{
            if(id!=b.id) return id<b.id;
            else return val>b.val;
        }
    }node[maxn];
    
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m;
        int u, v;
        for(int i=1; i<=n; i++){
            cin>>node[i].id>>node[i].val;
        }
        sort(node+1, node+1+n);
        int pre=-1;
        int c;
        int sum = 0;
        int ans = -1e9-10;
        for(int i=1; i<=n; i++){
            if(node[i].id!=pre){
                pre = node[i].id, c=0, sum = 0;
            }
            c++;
            sum +=node[i].val;
            if(sum>0) {
                a[c]+=sum;
            }
            ans = max(ans, a[c]);
        }
        if(ans == -1e9-10) cout<<0<<endl;
        else  cout<<ans<<endl;
    
        return 0;
    }
    

    D 构造题

    题意

    给n个点,每个点限制一个度数(a_i),你要构造一个无向图,使得每个点的度数不超过限制,并且最长链最长。

    题解

    度数大于等于2的点先构成一个最长链,然后度数为1的先加在两头(否则会使答案错误),之后的点在中间插就行了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    #define pb(x) push_back(x)
    #define cls(x, val) memset(x, val, sizeof(x))
    #define fi first
    #define se second
    #define mp(x, y) make_pair(x, y)
    #define inc(i, l, r) for(int i=l; i<=r; i++)
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 500+10;
    
    int readint()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n, m;
    int a[maxn];
    vector<int> lone;
    vector<int> two;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        int tot = 0;
        int one = 0;
        int sum = 0;
        int u, v;
        for(int i=1; i<=n; i++) {
            cin>>a[i];
            if(a[i]>1) tot += 1, two.push_back(i);
            else one+=1, lone.push_back(i);
            sum += a[i];
        }
        if(sum<2*n-2){
            cout<<"NO"<<endl;
            return 0;
        }
        {
            if(one>=2)
                cout<<"YES "<<tot+1<<endl<<n-1<<endl;
            else cout<<"YES "<<tot-1+one<<endl<<n-1<<endl;
            for(int i=0; i<two.size(); i++){
                if(i+1<two.size()){
                    u = two[i], v = two[i+1];
                    a[u]--, a[v]--;
                    cout<<u<<" "<<v<<endl;
                }
            }
            int idx = 0;
            if(lone.size()>=2){
                u=lone[0], v=lone[1];
                cout<<u<<" "<<two[0]<<endl;
                a[two[0]]--;
                cout<<v<<" "<<two[two.size()-1]<<endl;
                a[two[two.size()-1]]--;
                idx=2;
            }
            for(int i=0; i<two.size(); i++){
                int &deg = a[two[i]];
                if(idx >= int(lone.size())) break;
                for(int j=idx; j<min(int(lone.size()), deg+idx); j++){
                    cout<<lone[j]<<" "<<two[i]<<endl;
                }
                idx+=deg;
                deg = 0;
            }
        }
        return 0;
    }
    
    

    E Increasing Frequency--思维+贪心

    题意

    给一个长度为n的序列,并且确定一个数c。(你可以任选一个区间[l, r], 对该区间+k,k可以为负数),使得最后的n个数中,等于c的数字的个数最多。问最多有多少个这样的数?

    题解

    Let $ cnt(l,r,x) $ be a number of occurrences of number x in subsegment$ [l,r] $.

    The given task is equivalent to choosing ([l,r]) and value d, such that $ans=cnt(1,l−1,c)+cnt(l,r,d)+cnt(r+1,n,c) $is maximum possible. But with some transformations (ans=cnt(1,n,c)+(cnt(l,r,d)−cnt(l,r,c))), so we need to maximize (cnt(l,r,d)−cnt(l,r,c)).

    代码的精髓就是求解maximize(cnt(l, r, d)-cnt(l, r, c))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<stack>
    #include<set>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    #define pb(x) push_back(x)
    #define cls(x, val) memset(x, val, sizeof(x))
    #define fi first
    #define se second
    #define mp(x, y) make_pair(x, y)
    #define inc(i, l, r) for(int i=l; i<=r; i++)
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 5e5+10;
    
    int readint()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int cnt[maxn];
    int n, c;
    int mi[maxn];
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>c;
        int temp;
        int ans = 0;
        for(int i=1; i<=n; i++){
            cin>>temp;
            mi[temp] = min(mi[temp], cnt[temp]-cnt[c]);
            cnt[temp]++;
            ans = max(ans, cnt[temp]-cnt[c]-mi[temp]);
        }
        cout<<ans+cnt[c]<<endl;
    
        return 0;
    }
    

    F trie+dp

    G 最大密度子图

    题意

    给定一个无向图,给定边权和点权,选择若干的点,使得他们的边权和-点权和最大

    题解

  • 相关阅读:
    leetcode-383-Ransom Note(以空间换时间)
    AtCoder
    AtCoder
    Hadoop序列化案例实操
    Java实现MapReduce Wordcount案例
    HDFS常用API操作 和 HDFS的I/O流操作
    HBase常用的JAVA API操作
    ZooKeeper之服务器动态上下线案例
    机器学习(6)——逻辑回归
    机器学习(5)——多项式回归与模型泛化
  • 原文地址:https://www.cnblogs.com/babydragon/p/10042557.html
Copyright © 2020-2023  润新知