【NOIP2006 提高组】金明的预算方案


一道DP题,不知道为什么,2006年的题DP好像有点多。每个物件只有一个,有容量的上限,其实就是一道01背包。


dp【i】表示i元钱时候的所求的最大值,可以推出dp【i】=max{dp【i】,dp【i-v[j]】+w【j】};但这道题还有一个条件,附件只能在主件之后购买,所以我们就考虑购买这个物品之后去购买它的附件,因为最多只有2个附件,所以题还是比较简单的。


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int dp[32005],f[61][2],v[61],tot[61],tot_f[61][2];//tot表示价格和重要值的乘积,f表示一个物体和它的附件
int n,m;

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int p,q;
		cin>>v[i]>>p>>q;
		if(!q){//如果没有主件
			tot[i]=p*v[i];
			
		}
		else{//如果有主件,所属主件的附件数+1
			f[q][0]++;
			f[q][f[q][0]]=v[i];
			tot_f[q][f[q][0]]=v[i]*p;
		}
	}
	
	for(int i=1;i<=m;i++){
		for(int j=n;j>=v[i];j--){
			if(j>=v[i])//购买一个主件
			dp[j]=max(dp[j],dp[j-v[i]]+tot[i]);
			
			if(j>=v[i]+f[i][1])//一个主件和他的一个附件
			dp[j]=max(dp[j],dp[j-v[i]-f[i][1]]+tot[i]+tot_f[i][1]);
			
			if(j>=v[i]+f[i][1]+f[i][2])//一个主件和他的两个附件
			dp[j]=max(dp[j],dp[j-v[i]-f[i][1]-f[i][2]]+tot[i]+tot_f[i][1]+tot_f[i][2]);
		}
	}
	cout<<dp[n];
}

猜你喜欢

转载自blog.csdn.net/qq_41734244/article/details/80468887
今日推荐