金明的预算方案--依赖性背包

版权声明:转载请附上地址 https://blog.csdn.net/weixin_44574520/article/details/89790584

luogu 1064

在这里插入图片描述

Code:

#include <bits/stdc++.h>
using namespace std;
#define maxn 32110
#define maxm 70

int dp[maxm][maxn],c[maxm],w[maxm],n,m,man[maxm],man_f[maxm][maxm];

inline void init_() {
	freopen("a.txt","r",stdin);
}

inline int read_() {
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void clean_() {
	memset(dp,0,sizeof(dp));
	memset(man,0,sizeof(man));
	memset(man_f,0,sizeof(man_f));	
}

inline void readda_() {
	n=read_();m=read_();
	int x,y,z;
	for(int i=1;i<=m;i++) {
		x=read_();y=read_();z=read_();
		w[i]=x*y;c[i]=x;
		if(!z) man[++man[0]]=i;
		else man_f[z][++man_f[z][0]]=i;
	}
}

inline void work_() {
	for(int i=1;i<=man[0];i++) {
		int X=man[i];
		int W=w[X],C=c[X];
		//只选主件
		for(int j=n;j>=0;j--) {
			if(j>=C) dp[i][j]=max(dp[i-1][j],dp[i-1][j-C]+W);
			else dp[i][j]=max(dp[i-1][j],0);
		}
		//处理附件 
		if(man_f[X][0]<1) continue;
		C+=c[man_f[X][1]];
		W+=w[man_f[X][1]];
		//选一个主件和一号附件 
		for(int j=n;j>=0;j--) {
			if(j>=C) dp[i][j]=max(dp[i][j],dp[i-1][j-C]+W);
			else dp[i][j]=max(dp[i][j],0);
		}
		if(man_f[X][0]<2) continue;
		C+=c[man_f[X][2]];
		W+=w[man_f[X][2]];
		//选一个主件和两个附件 
		for(int j=n;j>=0;j--) {
			if(j>=C) dp[i][j]=max(dp[i][j],dp[i-1][j-C]+W);
			else dp[i][j]=max(dp[i][j],0);
	    }
	    C-=c[man_f[X][1]];
	    W-=w[man_f[X][1]];
	    //选一个主件和二号附件 
		for(int j=n;j>=0;j--) {
	    	if(j>=C) dp[i][j]=max(dp[i][j],dp[i-1][j-C]+W);
	    	else dp[i][j]=max(dp[i][j],0);
		}
	}
	printf("%d",dp[man[0]][n]);
}

int main() {
	init_();
	readda_();
	work_();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44574520/article/details/89790584