3 条题解

  • 0
    @ 2026-8-14 8:19:46

    你说得对,但我错解又过了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n,k,w[1000010],v[1000010];
    ll g[50010];
    vector<ll> vv[310],tot[310];
    bool cmp(ll a,ll b){
    	return a>b;
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	cin>>n>>k;
    	int fl=1;
    	for(int i=1;i<=n;i++){
    		cin>>w[i]>>v[i];fl&=w[i]==v[i];
    	}
    		for(int i=1;i<=n;i++){
    			vv[w[i]].push_back(v[i]);
    		}
    		for(int i=1;i<=300;i++)if(vv[i].size()){
    			sort(vv[i].begin(),vv[i].end(),cmp);
    			tot[i].push_back(0);
    			tot[i].push_back(vv[i][0]); 
    			for(int j=1;j<vv[i].size();j++){
    				tot[i].push_back(tot[i].back()+vv[i][j]);
    			}
    			for(int j=0;j<i;j++){
    				int len=(k-j)/i+1;
    				int l=j;
    				while(l<=k)l+=i;
    				l-=i;
    				int now=l;
    				for(;l>=j;l-=i){
    					if(now>l)now-=i;
    					while((l-now)/i<tot[i].size()-1&&now>j&&g[now]+tot[i][(l-now)/i]<g[now-i]+tot[i][(l-(now-i))/i])now-=i;
    					for(int p=now;p>=now-10*i&&p>=j&&(l-p)/i<tot[i].size();p-=i){
    						if(g[p]+tot[i][(l-p)/i]>g[now]+tot[i][(l-now)/i])now=p;
    						g[l]=max(g[l],g[p]+tot[i][(l-p)/i]);
    					}
    				} 
    			}
    		}
    		for(int i=1;i<=k;i++)cout<<g[i]<<" ";
    	return 0;
    }
    
    • 0
      @ 2026-8-13 20:17:07

      我还是第一次听说有分治 dp 这种东西(场上求出来个凸包觉得有滚木的作用)。

      #include<bits/stdc++.h>
      using namespace std;
      #define int long long
      const int N=310,inf=0x3f3f3f3f3f3f3f3f;
      vector<int>c[N],sum,f,g;
      int dp[50010];
      void dfs(int l,int r,int pl,int pr)
      {
      	if(l>r)return;
      	int mid=(l+r)>>1;
      	int bl=max(pl,mid-(int)sum.size()+1),br=min(pr,mid),mx=-inf,id=bl;
      	for(int i=bl;i<=br;i++)
      	{
      		int v=f[i]+sum[mid-i];
      		if(v>mx)mx=v,id=i;
      	}
      	g[mid]=mx;
      	dfs(l,mid-1,pl,id);
      	dfs(mid+1,r,id,pr);
      }
      signed main()
      {
      	int n,m;cin>>n>>m;
      	for(int i=1;i<=n;i++)
      	{
      		int x,y;cin>>x>>y;
      		c[x].push_back(y);
      	}
      	memset(dp,-0x3f,sizeof(dp));dp[0]=0;
      	for(int i=1;i<=300;i++)
      	{
      		if(c[i].empty())continue;
      		sort(c[i].begin(),c[i].end(),[](int x,int y){return x>y;});
      		sum.clear();sum.resize(c[i].size()+1);
      		for(int j=1;j<=c[i].size();j++)sum[j]=sum[j-1]+c[i][j-1];
      		for(int j=0;j<i;j++)
      		{
      			f.clear();
      			for(int k=j;k<=m;k+=i)f.push_back(dp[k]);
      			int cnt=f.size()-1;
      			g.assign(cnt+1,-inf);
      			dfs(0,cnt,0,cnt);
      			int id=0;
      			for(int k=j;k<=m;k+=i)dp[k]=g[id++];
      		}
      	}
      	for(int i=1;i<=m;i++)dp[i]=max(dp[i],dp[i-1]);
      	for(int i=1;i<=m;i++)cout<<dp[i]<<' ';cout<<'\n';
      	return 0;
      }
      • 0
        @ 2026-8-12 21:56:21

        #include<iostream>
        #include<cstdio>
        #include<algorithm>
        #include<vector>
        #define M 302
        #define K 50002
        #define N 1000002
        using namespace std;
        typedef long long ll;
        ll dp[2][K],g[2][K];
        int pre,now,pos,n,k,mx;
        vector<ll>vec[M];
        inline int rd(){
            int x=0;char c=getchar();bool f=0;
            while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
            while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
            return f?-x:x;
        }
        inline ll cmp(ll x,ll y){return x>y;}
        void solve(int l,int r,int L,int R,int sum){
            if(L>R||l>r)return;
            int mid=(L+R)>>1;ll num=0,point=-1;
            for(int i=max(mid-sum,l);i<=r&&i<mid;++i){
                if(g[pre][i]+vec[pos][mid-i-1]>num){
                    num=g[pre][i]+vec[pos][mid-i-1];point=i;
                }
            }
            if(point<0)point=l;
            g[now][mid]=num;
            solve(l,point,L,mid-1,sum);solve(point,r,mid+1,R,sum);
        }
        int main(){
            n=rd();k=rd();int x,y;
            for(int i=1;i<=n;++i){
                x=rd();y=rd();
                vec[x].push_back(y);mx=max(mx,x);
            }
            now=1;pre=0;
            for(int i=1;i<=mx;++i)if(vec[i].size()){
                pos=i;swap(now,pre);
                sort(vec[i].begin(),vec[i].end(),cmp);int x=vec[i].size(); 
                for(int j=1;j<x;++j)vec[i][j]+=vec[i][j-1];
                for(int j=0;j<i;++j){
                    int p=0;
                    for(int l=j;l<=k;l+=i,p++)g[pre][p]=dp[pre][l],g[now][p]=0;p--;
                    solve(0,p,0,p,vec[i].size());
                    for(int l=j,p=0;l<=k;l+=i,p++)dp[now][l]=max(dp[now^1][l],g[now][p]);
                }
            }
            for(int i=1;i<=k;++i)printf("%lld ",dp[now][i]);
            return 0;
        }
        
        • 1

        「雅礼集训 2017 Day5」珠宝 /「NAIPC2016」Jewel Thief

        信息

        ID
        10097
        时间
        2000ms
        内存
        256MiB
        难度
        9
        标签
        递交数
        28
        已通过
        3
        上传者