【2020.2.7 练习赛】 T3-蛋糕塔(dp-完全背包)

来源:JZOJ

题目描述

H l Hl 高中要举行一场蛋糕塔比赛。注意,不是 d o t a dota 比赛,而是蛋糕塔比赛。学校会提供 N N 种不同类型的蛋糕,第 i i 种蛋糕的高度为 H i Hi ( 5 < = H i < = T ) (5<=H i <=T ) ,营养价值为 V i Vi ( 1 < = V i < = 1 , 000 , 000 ) (1<=Vi<=1,000,000 ) ,并且保证所有蛋糕的高度为 5 5 的整数倍,每种类型的蛋糕没有数量限制。

蛋糕塔比赛的规则就是要求按照提供的蛋糕,垒成一个高度不超过 T T
( 1 < = T < = 1 , 000 ) (1<=T<=1,000 ) 的蛋糕塔,并且要求这个蛋糕塔所有蛋糕的营养价值累加和最高。

因为蛋糕不是很结实,参加比赛的小 x x 发现一个现象,如果某块蛋糕的高度超过 K K ,那么这块蛋糕下面的所有蛋糕的高度都将被压缩为自己高度的 4 / 5 4/5
4 / 5 4/5 ,但是营养价值不会丢失。发现这个情况后的小 x x 很兴奋,现在他想知道,如何安排自己的蛋糕塔,能让营养价值最高。

解题思路

  • 仍然是一道 d p dp (抹不去的心酸),显然是完全背包的变形,蛋糕能压缩,这个问题有点烦。那么,如何处理呢?O(∩_∩)O
  • 首先,我们不用超过 k k 的大蛋糕,就按小蛋糕做一遍完全背包,(如果完全背包不会的话,自行查资料)当然了,循环 j j 当然不只是枚举到 t t 了,考虑压缩的情况,应该枚举到 t 5 / 4 t*5/4
  • 然后再一重循环枚举大蛋糕, d p [ ( t h [ i ] ) 5 / 4 ] + v [ i ] dp[(t-h[i])*5/4]+v[i] 就是这个蛋糕放在最上面把下面所有的蛋糕压缩得到的营养价值,为什么 ( t h [ i ] ) 5 / 4 (t-h[i])*5/4 就是大蛋糕下面能达到的高度?因为我们想 t h [ i ] t-h[i] 是压缩后大蛋糕下面所有蛋糕的最大高度,它们都被压缩成了原来高度的 4 / 5 4/5 所以我们 5 / 4 *5/4 就是蛋糕压缩前能达到的最大高度,这样做就十分方便了;

Code

#include <bits/stdc++.h>
using namespace std;
int v[105],h[105],dp[2010];
int n,t,k,ans=0;
void Dp()
{
	memset(dp,0,sizeof(dp));
	for (int i=1;i<=n;i++)
	 for (int j=h[i];j<=t*5/4;j++)
	  dp[j]=max(dp[j],dp[j-h[i]]+v[i]);  //完全背包
}
void work()
{
	ans=dp[t];
	for (int i=1;i<=n;i++)
	 if (h[i]>=k) ans=max(ans,dp[(t-h[i])*5/4]+v[i]);  //取大蛋糕
}
int main()
{
	freopen("cheese..in","r",stdin);
	freopen("cheese..out","w",stdout);
	scanf("%d %d %d",&n,&t,&k);
	for (int i=1;i<=n;i++) scanf("%d %d",&v[i],&h[i]);
	Dp();
	work();
	printf("%d",ans);
	return 0;
}
发布了27 篇原创文章 · 获赞 33 · 访问量 1669

猜你喜欢

转载自blog.csdn.net/qq_43081996/article/details/104220643
今日推荐