题解:本题主要考查背包的变形。
简要题意:有n件食材,每件食材有属性,
a
i
a_i
ai,
b
i
bi
bi和
c
i
ci
ci,如果在
t
t
t时刻完成第
i
i
i样食材则得到
a
i
−
t
∗
b
i
ai-t*bi
ai−t∗bi的美味指数,用第i件食材做饭要花去ci的时间。求得美味指数最大。
1.背包变形:因为本题的价值是会变的,所以需要按优先度对所有点进行排序。
优先度推导:
列出先做x,y的代价
式1:
a
[
x
]
−
(
t
+
c
[
x
]
)
∗
b
[
x
]
+
a
[
y
]
−
(
t
+
c
[
x
]
+
c
[
y
]
)
∗
b
y
a[x]-(t+c[x])*b[x]+a[y]-(t+c[x]+c[y])*by
a[x]−(t+c[x])∗b[x]+a[y]−(t+c[x]+c[y])∗by
式2:
a
[
y
]
−
(
t
+
c
[
y
]
)
∗
b
[
y
]
+
a
[
x
]
−
(
t
+
c
[
y
]
+
c
[
x
]
)
∗
b
x
a[y]-(t+c[y])*b[y]+a[x]-(t+c[y]+c[x])*bx
a[y]−(t+c[y])∗b[y]+a[x]−(t+c[y]+c[x])∗bx
若式1>式2,则化简得c[x]*b[y]<c[y]*b[x]
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct N
{
long long a,b,c;
}t[999999];
long long dp[999999];
long long n,T,ans=-9999;
bool cmp(N x,N y)
{
return x.c*y.b<x.b*y.c;
}
int main()
{
cin>>T>>n;
for(int i=1;i<=n;i++)cin>>t[i].a;
for(int i=1;i<=n;i++)cin>>t[i].b;
for(int i=1;i<=n;i++)cin>>t[i].c;
sort(t+1,t+n+1,cmp);
for(int i=1;i<=n;i++)
for(int j=T;j>=t[i].c;j--)
dp[j]=max(dp[j],dp[j-t[i].c]+t[i].a-t[i].b*j);
for(int i=1;i<=T;i++)
ans=max(ans,dp[i]);
cout<<ans<<endl;
return 0;
}