luogu P2979 [USACO10JAN]奶酪塔Cheese Towers

这个题是一道奇怪的DP,大奶酪会把它下面的奶酪压扁(其实就是压成(4/5)),

如果说不考虑大奶酪会把其他的奶酪压扁,那么我们得到一个显然的规律:

塔中的奶酪可以任意交换顺序。

那么考虑我们要放一块大奶酪,把它放在那里好呢?肯定是最上面,(因为会把除它之外的所有奶酪压扁)

可是有的大奶酪太占空间了,是不能放的,而且我们又不能在DP的过程中判断奶酪的大小情况,

于是我想到了先确定大小情况,再DP,

先枚举放哪一块大奶酪(在最顶部),然后把剩下的奶酪高度都换算一下,跑背包。

对了,不要忘了枚举一块大奶酪都不放的情况,此时注意在DP过程中,不要涉及到任何一块大奶酪(开一个flag数组标记一下),



另外也许可以这么做:

将奶酪排序,(大奶酪在前),在DP的过程中判定是否有大奶酪,

但是这种做法在高度的控制上可能比较难,我没有尝试



下面是我的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
int n,k,t;
inline int ra()
{
	int x=0;char ch=getchar();int flag=1;
	while(ch>'9'||ch<'0'){if(ch=='-')flag=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x*=10;x+=ch-'0';ch=getchar();}
	return flag*x;
}
int h[500];
int v[500];
int ans;
bool big[500];
int dp[2000];
int main()
{
	n=ra();t=ra();k=ra();
	for(int i=1;i<=n;i++)
	{
		v[i]=ra();h[i]=ra();
        if(h[i]>=k)big[i]=1;
	}
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=t;j++)
	  {
	      if(j>=h[i]&&!big[i])dp[j]=max(dp[j],dp[j-h[i]]+v[i]);
	     // else dp[j]=dp[i-1][j];
	  }
	ans=max(ans,dp[t]);
	for(int now=1;now<=n;now++)
	if(big[now])
	{
		memset(dp,0,sizeof(dp));
		int nowt=((t-h[now])*5)/4;
		for(int i=1;i<=n;i++)
		  for(int j=1;j<=nowt;j++)
		  {
		  	if(j<h[i])dp[j]=dp[j];
		  	else dp[j]=max(dp[j],dp[j-h[i]]+v[i]);
		  }
		ans=max(ans,dp[nowt]+v[now]);
	}
	cout<<ans<<endl;
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值