• Educational Codeforces Round 61 (Rated for Div. 2) E 多重背包优化


    https://codeforces.com/contest/1132/problem/E

    题意

    有8种物品,重量是1~8,每种数量是(cnt[i])(1e16),问容量为W(1e18)的背包最多能装多少重量

    题解1

    • 多重背包二进制拆分物品转换成01背包,用map来剪枝掉无用的状态
    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    map<ll,bool>f,g;
    ll a[10],W,s[1005],ans;
    vector<ll>w;
    
    int main(){
    	cin>>W;
    	for(ll i=1;i<=8;i++){
    		cin>>a[i];
    		if(a[i]){
    			ans=max(ans,min(W/i,a[i])*i);
    			ll num=1;
    			while(a[i]>0){
    				w.push_back(min(num,a[i])*i);
    				a[i]-=min(num,a[i]);
    				num*=2;
    			}
    		}
    	}
    	sort(w.begin(),w.end());
    	reverse(w.begin(),w.end());
    	for(int i=w.size()-1;i>=0;i--)s[i]=s[i+1]+w[i];
    	f[0]=true;
    	for(int i=0;i<w.size();i++){
    		g.clear();
    		for(map<ll,bool>::iterator it=f.begin();it!=f.end();it++){
    			ll x=it->first;
    			g[x]=true;
    			if(x+w[i]<=W)g[x+w[i]]=true;
    		}
    		f.clear();
    		for(map<ll,bool>::iterator it=g.begin();it!=g.end();it++){
    			ll x=it->first;
    			if(x+s[i]<ans)continue;
    			f[x]=true;
    			ans=max(ans,x);
    		}
    	}
    	cout<<ans;
    }
    

    题解2

    参考:https://blog.csdn.net/qq_37451344/article/details/88860699

    • 设1到8的最小公倍数为lcm,则将lcm/V[i]看成一整份,然后枚举0到lcm/V[i]作为第二维
    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    const ll lcm=840;
    ll W,a[10],V[10],dp[10][10005],ans;
    int main(){
    	cin>>W;
    	for(int i=0;i<8;i++){
    		cin>>a[i];
    		V[i]=i+1;
    	}
    	memset(dp,-1,sizeof(dp));
    	dp[0][0]=0;
    	for(int i=0;i<8;i++){
    	    ll num=lcm/V[i];
    		ll end=min(num,a[i]);
    		for(int j=0;j<=lcm*8;j++){
    			if(dp[i][j]<0)continue;
    			for(int k=0;k<=end;k++){
    				if(j+k*V[i]<=lcm*8)dp[i+1][j+k*V[i]]=max(dp[i+1][j+k*V[i]],
    						dp[i][j]+(a[i]-k)/num);
    			}
    		}
    	}
    	for(int i=0;i<=lcm*8;i++){
    		if(i>W)break;
    		if(dp[8][i]<0)continue;
    		ans=max(ans,i+lcm*min(dp[8][i],(W-i)/lcm));
    	}
    	cout<<ans;
    }
    
  • 相关阅读:
    web前段知识
    如何查看服务器机型,如何查看软件的版本信息
    selenium server启动失败
    性能测试策略
    mysql_列出表中所有字段用逗号做分隔符
    复杂sql(1)
    orale建表查询
    javascript常用函数集
    orale用户角色管理
    数据流
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10809622.html
Copyright © 2020-2023  润新知