题目概述
一共有n件食材,每件食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。设计烹调方案使得美味指数最大。
对于40%的数据1<=n<=10
对于100%的数据1<=n<=50
所有数字均小于100,000
解题思路
这是一道01背包问题,但选择顺序对结果有影响。对于任意两件食材i和j,若i在j前面,则损失的美味指数为b[i]*c[i]+b[j]*(c[i]+c[j]);若j在i前,则损失的美味指数为b[j]*c[j]+b[i]*(c[i]+c[j])。由于美味指数只会随时间而减小,那么我们需要使损失的美味指数尽可能小:按b[i]*c[j]由小到大排序。
f[i,j]表示前i件
时间复杂度:O(nt)
空间复杂度:O(nt)
源程序
var
a,b,c:array[0..50]of longint;
d,f:array[0..100000]of int64;
i,j,n,m,t:longint;
ans:int64;
function max(a,b:int64):int64;
begin
if a>b then exit(a)
else exit(b);
end;
begin
readln(t,n);
for i:=1 to n do
read(a[i]);
readln;
for i:=1 to n do
read(b[i]);
readln;
for i:=1 to n do
read(c[i]);
for i:=1 to n-1 do
for j:=i+1 to n do
if b[i]*c[j]>b[j]*c[i] then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
b[0]:=b[i];
b[i]:=b[j];
b[j]:=b[0];
c[0]:=c[i];
c[i]:=c[j];
c[j]:=c[0];
end;
for i:=1 to n do
begin
d:=f;
fillchar(f,sizeof(f),0);
for j:=0 to t-c[i] do
f[j]:=max(d[j],d[j+c[i]]+a[i]-(t-j)*b[i]);
if t-c[i]>0 then
for j:=t-c[i]+1 to t do
f[j]:=d[j];
end;
ans:=0;
for i:=0 to t do
if ans<f[i] then ans:=f[i];
write(ans);
end.