站外题求救 背包(混合+分组)
  • 板块题目总版
  • 楼主__凉皮__
  • 当前回复5
  • 已保存回复5
  • 发布时间2021/7/19 16:14
  • 上次更新2023/11/4 14:10:17
查看原帖
站外题求救 背包(混合+分组)
259944
__凉皮__楼主2021/7/19 16:14

题意:

有 n 件物品v i 为价值,w i 为重量,t i为类型,p i 为数量,求重量最多m时的最大价值。

注意:当 p i = 0 时表示第 i 件物品有无数个。同一类型的物品只能拿一种,同一种可以拿多个。

话说洛谷上有类似题目吗?

其实就是一个混合背包+分组背包(单独的我会,然而合起来就不会了...),但我不知道怎么处理“同一种可以拿多个。”

以下奉上我的半成品代码:

#include<bits/stdc++.h>
using namespace std;
#define N 100000
int v[N+1],w[N+1],t[N][401],p[N+1],nt[N+1],dp[N+1];
int main(){
	int n=0,n1,zs=0,m;
	scanf("%d%d",&n1,&m);
	for(int i=1;i<=n1;i++){
		int z;
		n++;
		scanf("%d%d%d%d",&v[n],&w[n],&z,&p[n]);
		//cin>>v[n]>>w[n]>>z>>p[n];
		if(p[n]>1){
			int tw=1,n2=n-1;
			while(p[n]>1){//二进制优化
				if(p[n]>=tw)p[n]-=tw;
				else tw=p[n],p[n]=0;
				v[++n2]=v[n]*tw;
				w[n2]=w[n]*tw;
				t[z][++t[z][0]]=n2;
				tw*=2;
			}
			n=n2;
		}
		else{
			if(!p[n])p[n]=99999999;
			t[z][++t[z][0]]=n;
		}
	}		
	for(int i=1;i<=n1;i++){//分组背包模板
		if(!t[i][0])continue;
		for(int j=m;j>=1;j--)
			for(int k=1;k<=t[i][0];k++){
				int ki=t[i][k];
				if(j<w[ki])continue;
				dp[j]=max(dp[j],dp[j-w[ki]]+v[ki]);
			}
	}
	cout<<dp[m];
	
}
/*
4 4
3 1 1 3
7 2 1 1
4 3 2 5
6 4 3 4
*/

2021/7/19 16:14
加载中...