2022牛客寒假算法基础集训营3全部题解

Posted quinn18

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022牛客寒假算法基础集训营3全部题解相关的知识,希望对你有一定的参考价值。

文章目录


比赛链接


B 智乃买瓜 dp

题目链接
题意:
n n n 个物品重量为 a [ i ] ( 正 偶 数 ) a[i](正偶数) a[i]() ,可以买一整个或买一半或不买,问重量和为 1 , 2... m 1,2...m 12...m的方案数。
( 0 < = n < = 1 e 3 , 1 < = m < = 1 e 3 , 2 < a i < = 2 ∗ 1 e 3 ) (0<=n<=1e3,1<=m<=1e3, 2<ai<=2*1e3) (0<=n<=1e31<=m<=1e3,2<ai<=21e3)
题解:
d p [ i ] dp[i] dp[i] 表示重量和为 i i i 的方案数
转移方程为
i f ( j > = a [ i ] ) d p [ j ] + = d p [ j − a [ i ] ] if(j>=a[i]) dp[j]+=dp[j-a[i]] if(j>=a[i])dp[j]+=dp[ja[i]] d p [ j ] dp[j] dp[j] d p [ j − a [ i ] ] dp[j-a[i]] dp[ja[i]]的状态转移过来
i f ( j > = a [ i ] / 2 ) d p [ j ] + = d p [ j − a [ i ] / 2 ] if(j>=a[i]/2) dp[j]+=dp[j-a[i]/2] if(j>=a[i]/2)dp[j]+=dp[ja[i]/2]

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
int a[N];
int dp[N];
signed main() 
    ios_base::sync_with_stdio(0), cin.tie(0); cout.tie(0);
    int n, m;
    cin>>n>>m;
    for(int i=1; i<=n; i++) cin>>a[i];
    dp[0]=1;
    for(int i=1; i<=n; i++) 
        for(int j=m; j>=0; j--) 
            if(j>=a[i]) dp[j]=(dp[j]+dp[j-a[i]])%M;
            if(j>=a[i]/2) dp[j]=(dp[j]+dp[j-a[i]/2])%M;
        
     
     for(int i=1; i<=m; i++) 
        cout<<dp[i]%M<<" ";
     
    return 0;

C 智乃买瓜h dp

题目链接
题意:
知道重量和为 1 − m 1-m 1m的方案数,求有几个瓜怎么样的瓜。
( 0 < = n < = 1 e 3 , 1 < = m < = 1 e 3 , 2 < a i < = 2 ∗ 1 e 3 ) (0<=n<=1e3,1<=m<=1e3, 2<ai<=2*1e3) (0<=n<=1e31<=m<=1e3,2<ai<=21e3)
题解:
d p [ i ] dp[i] dp[i] 表示重量和为 i i i 的方案数
因为 d p [ 1 ] dp[1] dp[1] 可以确定原重量为 2 的瓜的个数
d p [ 2 ] dp[2] dp[2] 可以确定原重量为 4 的瓜的个数
a [ i ] a[i] a[i] 等于 i自己的个数 + 其他组合的和等于i 的方案数
i自己的个数 等于 d p [ i ] dp[i] dp[i] - 其他组合的和等于i 的方案数
i的方案数已知 其他组合的和等于i的方案数就是背包过来的

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
const int M=1e9+7; 
int in[N], inn[N];
pair<int, int> p[N];
vector<int> g;
int dp[N];
int a[N];
int num[N];
signed main() 
    ios_base::sync_with_stdio(0), cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    dp[0]=1;
    for(int i=1; i<=n; i++) 
        cin>>a[i];
    
    int cnt=0;
    for(int i=2; i<=n+n; i+=2) //枚举数量
        int p=((a[i/2]-dp[i/2]+M)%M);
        num[i]=p; 
        cnt+=num[i];
        for(int j=1; j<=p; j++) 
            for(int k=n; k>=0; k--) 
                if(k>=i) dp[k]=(dp[k]+dp[k-i])%M;
                if(k>=i/2) dp[k]=(dp[k]+dp[k-i/2])%M;
            
        
    
    cout<<cnt<<endl;
    if(cnt) 
        cout<<cnt<<endl;
        for(int i=1; i<=n+n; i++) 
            for(int j=1; j<=num[i]; j++) 
                //cout<<i<<" ";
            
        
        cout<<endl;
        return 0;
    else 
        cout<<1<<endl;
        cout<<n*2+2<<endl;
    
    return 0;


E 智乃的数字积木(easy version) 暴力模拟

题目链接
题意:

题解:
k好小
按照题意模拟
既然要最大的数字 就在相同颜色的块从大到小排序

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int N=1e6+5;
const int M=1e9+7;
int a[N];
int col[N]; 
set<int> v;
ll ksm(ll a,ll p)ll res=1;while(p)if(p&1)res=res*a%M;a=a*a%M;p>>=1;return res;
signed main() 
    ios_base::sync_with_stdio(0), cin.tie(0); cout.tie(0);
    int n, m, k;
    cin>>n>>m>>k;
    string s;
    cin>>s;
    for(int i=0; i<n; i++) 
        a[i+1]=s[i]-'0';
    
    for(int i=1; i<=n; i++) 
        cin>>col[i];
    
    int ks=1;
    for(int i=1; i<=n+1; i++) 
        if(col[i]==col[i-1])continue;
        else sort(a+ks, a+1+i-1, greater<int>()), ks=i;
    
    int o=0;
    for(int i=1; i<=n; i++) 
        o=o*10+a[i];
        o%=M;
    
    cout<<o<<endl;
    while(k--) 
        int p, q;
        cin>>p>>q;
        ks=1;
        for(int i=1; i<=n; i++) if(col[i]==p) col[i]=q;
        for(int i=1; i<=n+1; i++) 
            if(col[i]==col[i-1]) continue;
            else sort(a+ks, a+1+i-1, greater<int>()), ks=i;
        
        int o=0;
        for(int i=1; i<=n; i++) 
            o=o*10+a[i];
            o%=M;
        
        cout<<o%M<<endl;
    
    return 0;

F 智乃的数字积木(hard version) 【待补】

题目链接
题意:

题解:

G 智乃的树旋转(easy version) 思维

题目链接
题意:
现在智乃有一颗尺寸大小为 N N N 二叉树,智乃对其做了一次旋转操作将其打乱,她想让你通过一次树的旋转操作将其还原.
题解:
父亲-儿子 ->儿子-父亲

#include <bits/stdc++.h>
using namespace std; 
const int N=1e6+5; 
int a, n, b;
int in[N], inn[N]; 
signed main() 
    ios_base::sync_with_stdio(0), cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    for(int i=1; i<=n; i++) 
        int a, b;
        cin>>a>>b; 
        in[a]=i;
        in[b]=i;
    
    for(int i=1; i<=n; i++) 
        int a, b;
        cin>>a>>b; 
        inn[a]=i;
        inn[b]=i; 
    
    for(int i=1; i<=n; i++) 
        for(int j=1;

以上是关于2022牛客寒假算法基础集训营3全部题解的主要内容,如果未能解决你的问题,请参考以下文章

2022牛客寒假算法基础集训营 5 全部题解

2022牛客寒假算法基础集训营 5 全部题解

2022牛客寒假算法基础集训营6 全部题解

2022牛客寒假算法基础集训营6 全部题解

2022牛客寒假算法基础集训营1全部题解

2022牛客寒假算法基础集训营3题解 BCEFGHIJK