P1064 金明的預算方案 題解[NOIP2006TG]

題目地址

金明的題都出爛了怎麼我還在寫。。。依賴性揹包,把主件和它的附件看做一個集合,每個集合的決策只有5種:
1.全部不選
2.選主件
3.選主件和附件1
4.選主件和附件2
5.全選
把主件拉在一個數組計算01bag01bag即珂。
蒟蒻的垃圾碼風Code\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.我全都要
也就是對於每一個主件與附件集合的最優解,枚舉每個集合,得到全局最優
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章