牛客网暑期ACM多校训练营(第三场) A PACM Team

原来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;
}

猜你喜欢

转载自blog.csdn.net/PinkAir/article/details/81232356