2019.09.16 日常总结兼洛谷P1064题解

洛谷 P 1064 P1064 P1064

【题意】: 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

主件 附件

电脑 打印机,扫描仪

书柜 图书

书桌 台灯,文具

工作椅 无

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 0 0个、 1 1 1个或 2 2 2个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的 N N N元。于是,他把每件物品规定了一个重要度,分为 5 5 5等:用整数 1 − 5 1-5 15表示,第 5 5 5等最重要。他还从因特网上查到了每件物品的价格(都是 10 10 10元的整数倍)。他希望在不超过 N N N元(可以等于 N N N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

设第 j j j件物品的价格为 v [ j ] v[j] v[j]元,重要度为 w [ j ] w[j] w[j],则其价值为 v [ j ] × w [ j ] v[j]\times w[j] v[j]×w[j],设共选了 k k k件,分别为 j 1 , j 2 , j 3 , . . . , j k j_1,j_2,j_3,...,j_k j1,j2,j3,...,jk,则总价值为 ∑ i = 1 k v [ j i ] × w [ j i ] \sum^k_{i=1} v[j_i] \times w[j_i] i=1kv[ji]×w[ji]

请你帮助金明设计一个满足要求的购物单。
【思路】: 有 依 赖 的 有依赖的 01 01 01 背 包 的 经 典 题 背包的经典题 , , 由 于 每 个 东 西 最 多 有 由于每个东西最多有 西 2 2 2 个 附 件 , 所 以 我 们 可 以 直 接 暴 力 个附件,所以我们可以直接暴力 d p dp dp , , 具 体 策 略 如 下 : 具体策略如下:
1 1 1 、 只 选 主 件 自 己 、只选主件自己
2 2 2 、 选 主 件 、选主件 + + + 第 第 1 1 1 个 附 件 ( 有 且 装 得 下 的 话 ) 个附件(有且装得下的话)
3 3 3 、 选 主 件 、选主件 + + + 第 第 2 2 2 个 附 件 ( 有 且 装 得 下 的 话 ) 个附件(有且装得下的话)
4 4 4 、 选 主 件 、选主件 + 2 +2 +2 个 附 件 ( 有 且 装 得 下 的 话 ) 个附件(有且装得下的话)
所 以 所以 , , 这 道 题 思 路 其 实 并 不 难 这道题思路其实并不难 , , 难 就 难 在 代 码 实 现 上 难就难在代码实现上 , , 很 容 易 就 出 错 很容易就出错 , , 话 不 多 说 , 直 接 上 代 码 吧 话不多说,直接上代码吧 ! ! !
【代码】:

//By HPXXZYY
#include 
using namespace std;
int t[70][3]/*附件编号*/,a[70]/*附件个数*/,w[70]/*价格*/,p,x,tot/*主件个数*/;
int m,n,i,j,f[33000]/*dp用的数组*/,c[70]/*价值*/,q[70]/*主件编号*/;
int main(){
//	freopen("t1.in","r",stdin);
	scanf("%d%d",&m,&n);
	for(i=1;i<=n;i++){
		scanf("%d%d%d",&w[i],&p,&x);
		if (x==0) q[++tot]=i;
		else t[x][++a[x]]=i;
		c[i]=w[i]*p;
	}
	for(i=1;i<=tot;i++)
	for(j=m;j>=w[q[i]];j--){
		f[j]=max(f[j],f[j-w[q[i]]]+c[q[i]]);//策略1
		if (a[q[i]]&&j-w[q[i]]-w[t[q[i]][1]]>=0)//策略2
		f[j]=max(f[j],f[j-w[q[i]]-w[t[q[i]][1]]]+c[q[i]]+c[t[q[i]][1]]);
		if (a[q[i]]>1){
			if (j-w[q[i]]-w[t[q[i]][2]]>=0)//策略3
			f[j]=max(f[j],f[j-w[q[i]]-w[t[q[i]][2]]]+c[q[i]]+c[t[q[i]][2]]);
			if (j-w[q[i]]-w[t[q[i]][1]]-w[t[q[i]][2]]>=0)//策略4
			f[j]=max(f[j],f[j-w[q[i]]-w[t[q[i]][1]]-w[t[q[i]][2]]]+c[q[i]]+c[t[q[i]][1]]+c[t[q[i]][2]]);
		}
	}
	printf("%d",f[m]);
	return 0;
}

你可能感兴趣的:(原创)