依赖背包,转为01背包+分组背包
#include <stdio.h>
#include <memory.h>
#include <vector>
using namespace std;
int dp[3220];
struct Item {
int id;
int v,p;
};
int n,m;
Item items[70];
vector<Item> add_items[70];
int add_items_dp[70][3220];
int get_max(int a, int b) {
if (a>b)
return a;
else
return b;
}
void _01_dp() {
memset(add_items_dp,0,sizeof(add_items_dp));
int i,j,k;
Item tmp;
for (i=1;i<=m;i++) {
if (items[i].id==0)
continue;
for (j=0;j<add_items[i].size();j++) {
for (k=n-items[i].v;k>=add_items[i][j].v;k--)
add_items_dp[i][k]=get_max(add_items_dp[i][k], add_items_dp[i][k-add_items[i][j].v]+add_items[i][j].p);
}
add_items[i].clear();
tmp.v=0;
tmp.p=0;
//add_items[i].push_back(tmp);
for (k=n-items[i].v;k>0;k--) {
if (add_items_dp[i][k]!=add_items_dp[i][k-1]) {
tmp.v=k;
tmp.p=add_items_dp[i][k];
add_items[i].push_back(tmp);
}
}
}
}
void packet_dp() {
memset(dp,0,sizeof(dp));
int i,j,k;
for (i=1;i<=m;i++) {
if (items[i].id==0)
continue;
for (j=n;j>=items[i].v;j--) {
dp[j]=get_max(dp[j], dp[j-items[i].v]+items[i].p);
for (k=0;k<add_items[i].size();k++) {
if (j>=add_items[i][k].v+items[i].v)
dp[j]=get_max(dp[j], dp[j-add_items[i][k].v-items[i].v]+add_items[i][k].p+items[i].p);
}
}
}
}
int main() {
int i;
int v,p,q;
Item tmp;
while (scanf("%d",&n)!=EOF) {
scanf("%d",&m);
n=n/10;
for (i=0;i<70;i++)
add_items[i].clear();
for (i=1;i<=m;i++) {
scanf("%d%d%d",&v,&p,&q);
if (q==0) {
items[i].id=i;
items[i].v=v/10;
items[i].p=p*v/10;
}
else {
items[i].id=0;
tmp.v=v/10;
tmp.p=p*v/10;
add_items[q].push_back(tmp);
}
}
_01_dp();
packet_dp();
printf("%d\n", dp[n]*10);
}
return 0;
}
题目中提到:每个主件最多只有2个附件,所以也可以直接用分组背包解
#include <stdio.h>
#include <vector>
#include <memory.h>
using namespace std;
int n,m;
struct Item {
int id;
int v,p;
};
Item items[70];
int dp[3220];
vector<Item> _01_items[70];
vector<Item> add_items[70];
void set_01_items() {
int i;
Item tmp;
for (i=1;i<=m;i++) {
if (items[i].id==0)
continue;
_01_items[i].push_back(items[i]);
if (add_items[i].size()==1) {
tmp.v=items[i].v+add_items[i][0].v;
tmp.p=items[i].p+add_items[i][0].p;
_01_items[i].push_back(tmp);
}
if (add_items[i].size()==2) {
tmp.v=items[i].v+add_items[i][0].v;
tmp.p=items[i].p+add_items[i][0].p;
_01_items[i].push_back(tmp);
tmp.v=items[i].v+add_items[i][1].v;
tmp.p=items[i].p+add_items[i][1].p;
_01_items[i].push_back(tmp);
tmp.v=items[i].v+add_items[i][0].v+add_items[i][1].v;
tmp.p=items[i].p+add_items[i][0].p+add_items[i][1].p;
_01_items[i].push_back(tmp);
}
}
}
int get_max(int a, int b) {
if (a>b)
return a;
else
return b;
}
int main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
int i,j,k;
Item tmp;
int v,p,q;
while (scanf("%d",&n)!=EOF) {
scanf("%d",&m);
n=n/10;
for (i=0;i<70;i++) {
_01_items[i].clear();
add_items[i].clear();
}
for (i=1;i<=m;i++) {
scanf("%d%d%d",&v,&p,&q);
if (q!=0) {
items[i].id=0;
tmp.v=v/10;
tmp.p=p*tmp.v;
add_items[q].push_back(tmp);
}
else {
items[i].id=i;
items[i].v=v/10;
items[i].p=p*items[i].v;
}
}
set_01_items();
memset(dp,0,sizeof(dp));
for (i=1;i<=m;i++) {
if (_01_items[i].size()!=0) {
for (j=n;j>=0;j--) {
for (k=0;k<_01_items[i].size();k++) {
if (j>=_01_items[i][k].v)
dp[j]=get_max(dp[j], dp[j-_01_items[i][k].v]+_01_items[i][k].p);
}
}
}
}
printf("%d\n", dp[n]*10);
}
return 0;
}