限制条件:
- 一个主件有多个附件,可以选择不买和买几个
- 必须先购买主件再购买附件
所以对于一个主件最多有四种选择
这里使用位运算枚举所有选择,也可以用爆搜枚举
for(int y=0;y<1<<servent[i].size();y++)
{
int vv=master[i].first,ww=master[i].first*master[i].second;
for(int z=0;z<servent[i].size();z++)
if(y>>z&1)
vv+=servent[i][z].first,ww+=servent[i][z].second*servent[i][z].first;
if(x>=vv)
dp[x]=max(dp[x],dp[x-vv]+ww);
}
ac代码如下
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N=60,M=32010;
typedef pair<int,int> PII;
vector<PII> master(N);
vector<PII> servent[N];
int dp[M];
int main()
{
int n,m;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
int v,p,q;
cin>>v>>p>>q;
if(!q) //主件
master[i]={v,p};
else
servent[q].push_back({v,p});
}
for(int i=1;i<=n;i++)
{
if(!master[i].first&&!master[i].second) continue;
for(int x=m;x>=0;x--)
for(int y=0;y<1<<servent[i].size();y++)
{
int vv=master[i].first,ww=master[i].first*master[i].second;
for(int z=0;z<servent[i].size();z++)
if(y>>z&1)
vv+=servent[i][z].first,ww+=servent[i][z].second*servent[i][z].first;
if(x>=vv)
dp[x]=max(dp[x],dp[x-vv]+ww);
}
}
cout<<dp[m];
return 0;
}