P1064 金明的预算方案 题解[NOIP2006TG]

题目地址

金明的题都出烂了怎么我还在写。。。依赖性背包,把主件和它的附件看做一个集合,每个集合的决策只有5种:
1.全部不选
2.选主件
3.选主件和附件1
4.选主件和附件2
5.全选
把主件拉在一个数组计算 01 b a g 01bag 即珂。
蒟蒻的垃圾码风 C o d e \color{blue}Code

//2020/2/16 TOSHIBA i3-2328 2.5Hz FILCO圣手2代 百乐V5 晨光K-35
# include <bits/stdc++.h>
using namespace std;
const int N=32010;
int n,m;
int w[N][3];
int c[N][3];
int sonk[N];
int dp[N];
int zhujian[N];
int zk=0;
//vector <int> son[N];
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)) 
	{
		if(ch=='-') w=-1;
		ch=getchar();	
	}
	while(isdigit(ch)) 
	{
		s=(s<<1)+(s<<3)+ch-'0';
		ch=getchar();
	}
	return s*w;
}
void Input()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++) 
	{
		int _w=read(),_c=read(),_q=read();
		if(_q==0) 
		{
			w[i][0]=_w;
			c[i][0]=_c;
			zhujian[++zk]=i;
		}
		else
		{
			++sonk[_q];
			w[_q][sonk[_q]]=_w;
			c[_q][sonk[_q]]=_c;
		}
	}
	return ;
}
void solve()
{
	int P;
	for(int i=1;i<=zk;i++) 
	{
		P=zhujian[i];
		for(int j=n;j>=w[P][0];j--) 
		{
			dp[j]=max(dp[j],dp[j-w[P][0]]+c[P][0]*w[P][0]); //No choose and Only choose
			if(sonk[P]>=1&&j>=w[P][0]+w[P][1]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][1]]+c[P][0]*w[P][0]+c[P][1]*w[P][1]);
			if(sonk[P]>=2&&j>=w[P][0]+w[P][2]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][2]]+c[P][0]*w[P][0]+c[P][2]*w[P][2]);
			if(sonk[P]>=2&&j>=w[P][0]+w[P][1]+w[P][2]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][1]-w[P][2]]+c[P][0]*w[P][0]+c[P][1]*w[P][1]+c[P][2]*w[P][2]);
		}
	}
	printf("%d\n",dp[n]);
	return ;
}
int main(void) 
{
	Input();
	solve();
	return 0;
}
/*
每一次对于主件有5种决策:
1.屁都不选
2.选主件
3.选主件+附件1
4.选主件+附件2
5.我全都要
也就是对于每一个主件与附件集合的最优解,枚举每个集合,得到全局最优
*/
发布了18 篇原创文章 · 获赞 2 · 访问量 3447

猜你喜欢

转载自blog.csdn.net/woshidalaocxy/article/details/104340726