首页 > 其他分享 >The 2023 ICPC Nanjing Regional Contest G,F

The 2023 ICPC Nanjing Regional Contest G,F

时间:2023-11-11 13:46:32浏览次数:31  
标签:idx Contest int max Regional pos ICPC ans dp

G. 背包
我们要是选一个集合出来 并且免除k个宝石的话
我们一定是选最贵的k个宝石免费
这样我们的做法就是对wi排序
然后前面的做背包 后面直接贪心选vi最大的k个 这样是一定包含了最优解的
当然你可以用二分bit 也可以直接维护另一个dp

int n,tr1[200010],tr2[200010],idx;
map<int,int>mp;
int lowbit(int x){
    return x&-x;
}
void add(int x,int c,int tr[]){
    for(int i=x;i<=idx;i+=lowbit(i))tr[i]+=c;
}
int query(int x,int tr[]){
    int res=0;
    for(int i=x;i;i-=lowbit(i))res+=tr[i];
    return res;
}
void solve(){
    int w,k;cin>>n>>w>>k;
    vector<PII>a(n);
    for(int i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
        mp[a[i].second]++;
    }
    vector<int>mpp(n+1);
    for(auto [pos,w]:mp){
        mp[pos]=++idx;
        mpp[idx]=pos;
    }
    sort(all(a));
    int dp[n+1][w+1];
    memset(dp,0,sizeof dp);
    for(int i=1;i<=n;i++){
        auto [wi,vi]=a[i-1];
        for(int j=1;j<=w;j++){
            dp[i][j]=dp[i-1][j];
            if(j>=wi)dp[i][j]=max(dp[i][j],dp[i-1][j-wi]+vi);
        }
    }
    int ans=dp[n][w];
    for(int i=n;i>=0;i--){
        int mx=*max_element(dp[i],dp[i]+w+1);
        int l=1,r=idx;
        while(l<r){
            int mid=l+r>>1;
            int x=mid;
            if(query(idx,tr1)-query(x-1,tr1)<=k)r=mid;
            else l=mid+1;
        }
        int cnt=query(idx,tr1)-query(l-1,tr1);
        if(cnt>=k){
            ans=max(ans,mx+query(idx,tr2)-query(l-1,tr2)-mpp[l]*(cnt-k));
        }else{
            ans=max(ans,mx+query(idx,tr2)-query(l-1,tr2));
        }
//        cout<<mx<<' '<<query(idx,tr2)-query(l-1,tr2)<<' '<<l<<endl;
        if(i) {
            auto [wi,vi]=a[i-1];
            add(mp[vi], 1, tr1);
            add(mp[vi], vi, tr2);
        }
    }
    cout<<ans<<endl;
}
int g[5010][5010];
void solve(){
    int w,k;cin>>n>>w>>k;
    vector<PII>a(n);
    for(int i=0;i<n;i++){
        cin>>a[i].first>>a[i].second;
        mp[a[i].second]++;
    }
    vector<int>mpp(n+1);
    for(auto [pos,w]:mp){
        mp[pos]=++idx;
        mpp[idx]=pos;
    }
    sort(all(a));
    int dp[n+1][w+1];
    memset(dp,0,sizeof dp);
    for(int i=1;i<=n;i++){
        auto [wi,vi]=a[i-1];
        for(int j=1;j<=w;j++){
            dp[i][j]=dp[i-1][j];
            if(j>=wi)dp[i][j]=max(dp[i][j],dp[i-1][j-wi]+vi);
        }
    }
    int ans=dp[n][w];
    for (int i = n; i; i--) {
        for (int j = k; j >= 0; j--) {
            if (j >= 1) g[i][j] = max(g[i + 1][j], g[i + 1][j - 1] + a[i-1].second);
            else g[i][j] = g[i + 1][j];
        }
        ans = max(ans, dp[i - 1][w] + g[i][k]);
    }
    cout<<ans<<endl;
}

F. 等价重写
我们发现我们该点的一位 只和最后这一位是什么联系
也就是最后一位必须在最后 这样我们就可以把当前与最后连起来 表示我该点必须在这个点之前
其他我都可以不管
然后拓扑排序 要是有一层是两个入队 表示我这两个谁前谁后都可以 就可以交换顺序

void solve(){
    int n,m;cin>>n>>m;
    vector<int>v[n+1],last(m+1);
    vector<int>g[n+1],deg(n+1);
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        while(x--){
            int pos;cin>>pos;
            v[i].push_back(pos);
            last[pos]=i;
        }
    }
    for(int i=1;i<=n;i++){
        for(auto pos:v[i]){
            if(i!=last[pos]){
                g[i].push_back(last[pos]);
                deg[last[pos]]++;
            }
        }
    }
    vector<int>q;
    for(int i=1;i<=n;i++){
        if(!deg[i])q.push_back(i);
    }
    while(q.size()){
        if(q.size()>=2){
            cout<<"Yes"<<endl;
            int mx=max(q[0],q[1]),mn=min(q[0],q[1]);
            for(int j=1;j<=n;j++){
                if(mx==j)continue;
                if(j==1){
                    if(j==mn){
                        cout<<mx<<' '<<mn;
                    }else{
                        cout<<j;
                    }
                }
                else {
                    if(j==mn){
                        cout<<' '<<mx<<' '<<mn;
                    }else{
                        cout<<' '<<j;
                    }
                }
            }cout<<endl;
            return;
        }
        vector<int>nq;
        while(q.size()){
            auto u=q.back();q.pop_back();
            for(auto v:g[u]){
                deg[v]--;
                if(deg[v]==0){
                    nq.push_back(v);
                }
            }
        }
        q=nq;
    }
    cout<<"No"<<endl;
}

标签:idx,Contest,int,max,Regional,pos,ICPC,ans,dp
From: https://www.cnblogs.com/ycllz/p/17825834.html

相关文章

  • Kattis - A Complex Problem (The 2023 ICPC Rocky Mountain Regional Contest)
    IntroThiswasoneoftheproblemsIdidn'tdoduringtheregionalcontest.Oneofmyteammatessolvedit.ObservationTherearefewthingstonote.Firsttypeofnotation:subsetmeansthatA$\subset$B,buttherecanbecasesthatsubsetforms......
  • AtCoder Beginner Contest(abc) 322
    B-PrefixandSuffix难度:⭐题目大意给定两个字符串t和s,如果t是s的前缀则输出1,如果是后缀则输出2,如果都是则输出0,都不是则输出3;解题思路暴力即可;神秘代码#include<bits/stdc++.h>#defineintl1ngl1ng#defineIOSios::sync_with_stdio(false),cin.......
  • The 10th Jimei University Programming Contest
    外校打星队伍,排名22/450,还算凑合吧。A.A+B问题直接枚举进制#include<bits/stdc++.h>usingnamespacestd;usingvi=vector<int>;voidsolve(){stringstr;via,b,s;cin>>str;for(autoc:str){if(c>='0'and......
  • vp ICPC2020 沈阳
    ProblemK.ScholomanceAcademy机器学习题解:做的时候没认真读题,把+和数字的作用搞反了,后面写完程序发现算的数正好反过来,又重新读了一遍题目.显然我们发现,对于\(\theta\),可以直接取\(s\).取其余的值是可以等价过来的分别把实际为+和-的加到\(P,N\)中对于......
  • 2023ICPC南京站回忆录
    某种程度上来说集齐了金银铜铁,南京也因此成了刻在心底里的一道深深的痕迹。============================icpc南京站赛后总结  打得一言难尽,分析起来又说来话长。最后是3题,罚时很多,离铜线10名左右。如果罚时少一点也不至于打铁。如果能再开一题也不至于打铁。罚时多的原因:......
  • AtCoder Beginner Contest(abc) 320
    B-LongestPalindrome难度:⭐题目大意找一个字符串中最长的回文子串解题思路数据不大,暴力即可;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#defineendl'\n'usingnamespaces......
  • ICPC 2023 南京站:渐入佳境
    前言第一次ICPC!虽然不是第一次XCPC现场赛了,但是第一个ICPCAu还是浅浅地记录一下叭~一如既往的,这次旅游性质很重,在南京胡吃海喝了(x)Day1热身赛,四个袋鼠题,似乎南京站往年都会有一个袋鼠题,应该这次也是不例外的。队长这次在酒店里睡觉,虽然来了大概也是睡觉(但是这次的热......
  • AtCoder Beginner Contest 327 (ABC327)
    A.ab直接根据题意模拟即可。CodeB.A^A直接枚举\(i=1,2,\dots,15\),每次看看\(i^i\)是否等于\(A\)即可。CodeC.NumberPlaceDescription给你一个\(9\times9\)的矩阵\(A\),判断是否合法,满足以下三个条件,即为合法。对于每一行,包含数字\(1\sim9\);对于......
  • AtCoder Beginner Contest(abc) 319
    B-Measure难度:⭐题目大意给定一个数N,我们要求输出长度为n+1的一个序列Si(i从0到n),对于Si,如果存在j(j从1~9)是N的一个除数,并且i是N/j的一个倍数,那么Si就是满足条件的最小的j,如果没存在就输出'-';解题思路数据不大,暴力即可;神秘代码#include<bits/st......
  • 2022ICPC济南
    目录E.IdenticalParityK.StackSort2022InternationalCollegiateProgrammingContest,JinanSitecf传送门E.IdenticalParity无论k怎么给定,k个数里面奇数个数要么和偶数相等,要么奇数比偶数多一个(因为总体的奇数个数可能比偶数个数多一个),此时再利用余数去补足即可......