P1064 [NOIP2006 提高组] 金明的预算方案(DP)

可以将分组的背包看成若干个01背包来做。

#include<cstdio>
#include<iostream>
using namespace std;
int read(){
	int num=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		num=num*10+c-'0';
		c=getchar();
	}
	return num*f;
}
int n,m;
int v[65][3],p[65][3];
int cnt;
int f[32005];
int main(){
	n=read(); m=read();
	for(int i=1;i<=m;i++){
		int vv=read(),pp=read(),qq=read();
		if(qq==0){
			v[i][0]=vv;
			p[i][0]=pp*vv;
		}
		else if(!v[qq][1]){
			v[qq][1]=vv;
			p[qq][1]=pp*vv;
		}
		else{
			v[qq][2]=vv;
			p[qq][2]=pp*vv;
		}
	}
	for(int i=1;i<=m;i++){
		for(int j=n;j>=1;j--){
			if(j-v[i][0]>=0){
				f[j]=max(f[j],f[j-v[i][0]]+p[i][0]);
			}
			if(j-v[i][0]-v[i][1]>=0){
				f[j]=max(f[j],f[j-v[i][0]-v[i][1]]+p[i][0]+p[i][1]);
			}
			if(j-v[i][0]-v[i][1]-v[i][2]>=0){
				f[j]=max(f[j],f[j-v[i][0]-v[i][1]-v[i][2]]+p[i][0]+p[i][1]+p[i][2]);
			}
		}
	}
	printf("%d",f[n]);
	return 0;
}
上一篇:9.29模拟赛


下一篇:【Loj #10100. 「一本通 3.6 练习 1」网络】题解