方法一:最容易懂的一种方法,转换为01背包思路
#include <iostream>
#include <cmath>
using namespace std;
#define MAX_M 32000
#define MAX 62
int dp[MAX_M][MAX];
int master[MAX];
int c[MAX][3];
int tv[MAX][4];
int tw[MAX][4];
int cnt[MAX];
struct Node{
int v,p;
}node[MAX];
void package(int x)
{
int m=master[x];
if (c[m][0]==0)
{
tv[x][0]=node[m].p;
tw[x][0]=node[m].v;
cnt[x]=1;
}else if (c[m][0]==1)
{
tv[x][0]=node[m].p;
tw[x][0]=node[m].v;
tv[x][1]=node[m].p+node[c[m][1]].p;
tw[x][1]=node[m].v+node[c[m][1]].v;
cnt[x]=2;
}else if (c[m][0]==2)
{
tv[x][0]=node[m].p;
tw[x][0]=node[m].v;
tv[x][1]=node[m].p+node[c[m][1]].p;
tw[x][1]=node[m].v+node[c[m][1]].v;
tv[x][2]=node[m].p+node[c[m][2]].p;
tw[x][2]=node[m].v+node[c[m][2]].v;
tv[x][3]=node[m].p+node[c[m][1]].p+node[c[m][2]].p;
tw[x][3]=node[m].v+node[c[m][1]].v+node[c[m][2]].v;
cnt[x]=4;
}
}
int dfs(int n,int s)
{
if (dp[n][s]>=0)
{
return dp[n][s];
}
if (s==0||n<0)
{
dp[n][s]=0;
return dp[n][s];
}
package(s);
dp[n][s]=dfs(n,s-1);
for (int i=0;i<cnt[s];i++ )
{
if (n>=tw[s][i])
{
dp[n][s]=max(dp[n][s],dfs(n-tw[s][i],s-1)+tv[s][i]);
}
}
return dp[n][s];
}
int main()
{
int cur=0;
int n,m; cin>>n>>m;
n/=10;
int v,p,q;
for (int i=0;i<=m;i++){
c[i][0]=0;
}
for (int i=1;i<=m;i++){
cin>>v>>p>>q;
v/=10;
node[i].v=v;
node[i].p=v*p;
if (q==0)
{
master[++cur]=i;
}else{
c[q][++c[q][0]]=i;
}
}
for (int i=0;i<=n;i++){
for (int j=0;j<=cur;j++){
dp[i][j]=-1;
}
}
cout<<dfs(n,cur)*10<<endl;
return 0;
}
方法二:
#include <iostream>
#include <cmath>
using namespace std;
#define MAX_M 32000
#define MAX 62
int dp[MAX_M];
int c[MAX][3];
int tv[4];
int tw[4];
int cnt;
struct Node{
int v,p,q;
}node[MAX];
void package(int m)
{
if (c[m][0]==0)
{
tv[0]=node[m].p;
tw[0]=node[m].v;
cnt=1;
}else if (c[m][0]==1)
{
tv[0]=node[m].p;
tw[0]=node[m].v;
tv[1]=node[m].p+node[c[m][1]].p;
tw[1]=node[m].v+node[c[m][1]].v;
cnt=2;
}else if (c[m][0]==2)
{
tv[0]=node[m].p;
tw[0]=node[m].v;
tv[1]=node[m].p+node[c[m][1]].p;
tw[1]=node[m].v+node[c[m][1]].v;
tv[2]=node[m].p+node[c[m][2]].p;
tw[2]=node[m].v+node[c[m][2]].v;
tv[3]=node[m].p+node[c[m][1]].p+node[c[m][2]].p;
tw[3]=node[m].v+node[c[m][1]].v+node[c[m][2]].v;
cnt=4;
}
}
int main()
{
int n,m; cin>>n>>m;
n/=10;
int v,p,q;
for (int i=0;i<=m;i++){
c[i][0]=0;
}
for (int i=1;i<=m;i++){
cin>>v>>p>>q;
v/=10;
node[i].v=v;
node[i].p=v*p;
node[i].q=q;
if (q){
c[q][++c[q][0]]=i;
}
}
for (int i=0;i<=n;i++){
dp[i]=0;
}
for (int i=1;i<=m;i++)
{
if (node[i].q) continue;
package(i);
for (int j=n;j>=node[i].v;j--)
{
for (int k=0;k<cnt;k++)
{
if (j>=tw[k])
{
dp[j]=max(dp[j],dp[j-tw[k]]+tv[k]);
}
}
}
}
cout<<dp[n]*10<<endl;
return 0;
}