中石大第39次CSP培训Week4题解

A.最长上升子序列


Key:动态规划—线性DP

AC代码

未优化版

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 5010, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int dp[N];
    int ans=0;

    void solve(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            dp[i]=1;
        }
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<i;j++){
                if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);
                ans=max(ans,dp[i]);
            }
        }
        cout<<ans<<endl;
        return ;
    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

二分优化

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 1e5+10, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int dp[N];
    vector<int> v;

    void solve(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        v.pb(a[1]);
        for(int i=2;i<=n;i++){
            if(a[i]>v[v.size()-1])v.pb(a[i]);
            else{
                int p=lower_bound(v.begin(),v.end(),a[i])-v.begin();
                v[p]=a[i];
            }
        }
        cout<<v.size()<<endl;
        return ;

    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

B.编辑距离


Key:动态规划—线性DP

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 2010, MAX = 1e9, INF = -1e9;

    string a,b;
    int dp[N][N];

    void solve(){
        cin>>a>>b;
        int n=a.size();int m=b.size();
        a=" "+a;b=" "+b;
        for(int i=1;i<N;i++)dp[i][0]=dp[0][i]=i;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
                dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (a[i] != b[j]));
            }
        }
        cout<<dp[n][m]<<endl;
        return ;
    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

C.采药


Key:动态规划—背包问题—01背包

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 105, MAX = 1e9, INF = -1e12, M = 1005;

    int n,V;
    int v[N];
    int w[N];
    int dp[N][M];

    void solve(){
    	cin>>V>>n;
    	for(int i=1;i<=n;i++){
    		cin>>v[i]>>w[i];
    	}
    	memset(dp,0,sizeof dp);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=V;j++){
    			dp[i][j]=dp[i-1][j];
    			if(j-v[i]>=0)dp[i][j]=max(dp[i][j],dp[i-1][j-v[i]]+w[i]);
    		}
    	}
    	cout<<dp[n][V]<<endl;

    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

D.第37次CSP认证第二题:机器人饲养指南


Key:动态规划—背包问题—完全背包

AC代码

未优化版

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 105, MAX = 1e9, INF = -1e12, M = 10005;

    int n,m;
    int w[N];
    int dp[N][M];
    void solve(){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            cin>>w[i];
        }
        memset(dp,0,sizeof dp);
        for(int i=1;i<=m;i++){
            for(int j=0;j<=n;j++){
                for(int k=0;k*i<=j;k++){
                    dp[i][j]=max(dp[i][j],dp[i-1][j-k*i]+k*w[i]);
                }
            }
        }
        cout<<dp[m][n]<<endl;

    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

优化版

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 105, MAX = 1e9, INF = -1e12, M = 10005;

    int n,m;
    int w[N];
    int dp[N][M];
    void solve(){
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		cin>>w[i];
    	}
    	memset(dp,0,sizeof dp);
    	for(int i=1;i<=m;i++){
    		for(int j=0;j<=n;j++){
    			dp[i][j]=dp[i-1][j];
    			if(j>=i)dp[i][j]=max(dp[i][j],dp[i][j-i]+w[i]);
    		}
    	}
    	cout<<dp[m][n]<<endl;
    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

E.石子合并(弱化版)


Key:动态规划—区间DP

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 305, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int dp[N][N];
    int s[N];

    void solve(){
        cin>>n;
        memset(dp,0x3f,sizeof dp);
        for(int i=1;i<=n;i++){
            cin>>a[i];
            dp[i][i]=0;
            s[i]=s[i-1]+a[i];
        }

        for(int len=1;len<=n;len++){
            for(int i=1;i<=n-len;i++){
                int l=i;int r=i+len;
                for(int k=l;k<=r-1;k++){
                    dp[l][r]=min(dp[l][k]+dp[k+1][r]+s[r]-s[l-1],dp[l][r]);
                }
            }
        }
        cout<<dp[1][n]<<endl;
        return ;

    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

另解:记忆化搜索

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 305, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int s[N];
    int dp[N][N];

    int dfs(int l,int r){
        if(r==l){
            return 0;
        }
        int &ans=dp[l][r];
        if(ans!=-1)return ans;
        ans=MAX;
        for(int k=l;k<r;k++){
            ans=min(ans,dfs(l,k)+dfs(k+1,r)+a[r]-a[l-1]);
        }
        return ans;
    }

    void solve(){
        cin>>n;
        memset(dp,-1,sizeof dp);
        for(int i=1;i<=n;i++){
            cin>>a[i];
            a[i]+=a[i-1];
        }
        cout<<dfs(1,n)<<endl;
    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }

F.没有上司的舞会


Key:动态规划—树形DP

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    #define val(a) (a<'a' ? (a-'A'+'a') : a)
    #define fast() ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
    using namespace std;

    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef pair<long long, long long> PLL;
    typedef priority_queue<int> PQ;
    typedef priority_queue<int, vector<int>, greater<int>> Q;
    const int N = 2e5+10, MAX = 1e9, INF = -1e9;


    int n;
    int e[N];
    bool st[N];
    vector<vector<int>> v(N);
    int root;
    int dp[N][2];

    void dfs(int p){
        dp[p][1]+=e[p];
        for(auto i:v[p]){
            dfs(i);
            dp[p][1]+=dp[i][0];
            dp[p][0]+=max(dp[i][0],dp[i][1]);
        }
        
    }

    void solve(){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>e[i];
        for(int i=1;i<=n-1;i++){
            int l,r;
            cin>>l>>r;
            st[l]=true;
            v[r].pb(l);
        }
        for(int i=1;i<=n;i++){
            if(!st[i]){
                root=i;
                break;
            }
        }
        dfs(root);
        cout<<max(dp[root][0],dp[root][1])<<endl;
        return ;

    }

    signed main()
    {
        fast();
        
        int t=1;
        //cin>>t;
        while(t--){
            solve();
        }
        return 0;
    }
posted @ 2025-07-28 11:15  Oaths  阅读(30)  评论(0)    收藏  举报