有 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
*/