原来dp开了五维,用来存数据,同时可以通过数据的大小变化来回溯求路径,结果内存超了,只能变成四个维度然后再开一个五维的来记录记路径。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Max int(1e5+10)
const ll N=1000+10;
int n;
short int a[40],p[40],c[40],m[40],g[40];
short int dp[40][40][40][40],vis[40][40][40][40][40];
int P,A,C,M;
int main() {
int x,y;
while(~scanf("%d",&n)) {
for(int i=1; i<=n; i++)
scanf("%d%d%d%d%d",&p[i],&a[i],&c[i],&m[i],&g[i]);
scanf("%d%d%d%d",&P,&A,&C,&M);
memset(dp,0,sizeof dp);
memset(vis,0,sizeof vis);
int num=0;
for(int i=1; i<=n; i++) {
for(int j=P; j>=p[i]; j--) {
for(int k=A; k>=a[i]; k--) {
for(int x=C; x>=c[i]; x--) {
for(int y=M; y>=m[i]; y--) {
if(dp[j][k][x][y]<dp[j-p[i]][k-a[i]][x-c[i]][y-m[i]]+g[i])
{
dp[j][k][x][y]=dp[j-p[i]][k-a[i]][x-c[i]][y-m[i]]+g[i];
vis[i][j][k][x][y]=1;
}
}
}
}
}
}
int *b=new int[n+1];
while(n)
{
if(vis[n][P][A][C][M])
{
b[++num]=n-1;
P-=p[n];
A-=a[n];
C-=c[n];
M-=m[n];
}
n--;
}
if(num==0)
printf("0\n");
else
{
printf("%d\n",num);
for(int i=num;i>0;i--)
if(i==num)
printf("%d",b[i]);
else
printf(" %d",b[i]);
printf("\n");
}
}
return 0;
}