luogu1417:烹调方案:01背包ex

93 篇文章 0 订阅
78 篇文章 0 订阅

题目连接

  • 该题是luogu试炼场的2-17:T4

题目大意

  1. 01背包问题+了难度。

题目分析

  • 因为价值与次序有关,所以在普通的01背包基础上,假如了次序的概念,需要先进行特殊排序,再跑背包。


解题思路
  • 用结构体来表述每样物品:k[i]物品的属性包括:a,b,c;

  • 区别于传统的背包,题目中设定了价值:a-t*b,所以一个物品先枚举和后枚举,价值是会发生变化的;

  • 设定k[x]和k[y]进行比较:
    如果先取x,再取y:
    k[x].a - (t+k[x].c) * k[x].b + k[y].a - (t+ k[x].c+ k[y].c) * k[y].b
    如果先取y,再取x:
    k[y].a - (t+k[y].c) * k[y].b + k[x].a - (t+ k[y].c+ k[x].c) * k[x].b

  • 由以上式子推出优先级别关系:
    x与y的关系由:k[x].c * k[y].bk[y].c * k[x].b 来决定。


参考代码
//luogu1417:烹调方案:01背包ex
//先排序再背包 
 
#include<bits/stdc++.h>
using namespace std;
#define ma 100005
#define ll long long

struct nod{ll a,b,c; }k[ma];
ll f[ma],ans=0;
int t,n;

bool cmp(nod x,nod y)
{
	return x.c*y.b<y.c*x.b;
}

int main()
{
	scanf("%d %d",&t,&n);
	
	for(int i=1;i<=n;i++) scanf("%d",&k[i].a);
	for(int i=1;i<=n;i++) scanf("%d",&k[i].b);
	for(int i=1;i<=n;i++) scanf("%d",&k[i].c);
	
	sort(k+1,k+1+n,cmp);
	
	for(int i=1;i<=n;i++)
	{
		for(int j=t;j>=k[i].c;j--)
		{
			f[j]=max(f[j],f[j-k[i].c]+k[i].a-j*k[i].b);
		}
	}
	
	for(int i=1;i<=t;i++)
	{
		ans=max(f[i],ans);
	}
	
	printf("%d",ans);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值