题目连接
- 该题是luogu试炼场的2-17:T4
题目大意
- 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].b 和 k[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;
}