• Codeforces 1442D Sum dp+分治


    Codeforces 1442D Sum

    题意

    (n)个单调不减的数组,你可以做(k)次操作,每次选择一个数组,取走第一个数字。

    (n,kle 3000)

    分析

    官方题解给出的结论:最优方案一定是将部分数组全部取完,再选择一个数组取走一部分。

    可以枚举将哪个数组取一部分,另外(n-1)个数组取完或不取完用01背包求一下,但是这样还是(O(kn^2))的,可以分治,当分治区间长度为1时计算一下答案。

    Code

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<sstream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<map>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e5+10;
    const int inf=1e9;
    int n,K;
    int b[3010];
    ll a[3010][3010];
    ll dp[3010<<2][3010];
    ll ans;
    void dfs(int l,int r,int p){
        if(l==r){
            for(int i=0;i<=b[l];i++) ans=max(ans,dp[p][K-i]+a[l][i]);
            return;
        }
        int mid=l+r>>1;
        memcpy(dp[p<<1],dp[p],sizeof dp[p]);
        memcpy(dp[p<<1|1],dp[p],sizeof dp[p]);
        for(int i=mid+1;i<=r;i++){
            for(int j=K;j>=b[i];j--)
                dp[p<<1][j]=max(dp[p<<1][j],dp[p<<1][j-b[i]]+a[i][b[i]]);
        }
        for(int i=l;i<=mid;i++){
            for(int j=K;j>=b[i];j--) 
                dp[p<<1|1][j]=max(dp[p<<1|1][j],dp[p<<1|1][j-b[i]]+a[i][b[i]]);
        }
        dfs(l,mid,p<<1);dfs(mid+1,r,p<<1|1);
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>K;
        for(int i=1;i<=n;i++){
            cin>>b[i];
            rep(j,1,b[i]){
                int x;
                cin>>x;
                if(j<=K) a[i][j]=a[i][j-1]+x;
            }
            b[i]=min(b[i],K);
        }
        dfs(1,n,1);
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    【原】相煎何太急——input的blur事件与button的click事件
    【原】jQuery与CSS自动生成验证码
    【转】HTML转义字符大全
    【原】来自于一位前端“布道者”的建议
    【原】如何在jQuery中实现闭包
    【转】Web前端研发工程师编程能力飞升之路
    【原】git如何删除本地和远程的仓库
    H5不同样式新闻垂直滚动效果
    mui防止软键盘弹起方法
    js显示对象所有属性和方法的函数
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13949342.html
Copyright © 2020-2023  润新知