算法:DP
分析:一个经典的多重背包问题。每一个物品按原价出售也可以看成是一种优惠方案,因此一共有N+M种优惠方案,然后用这N+M种优惠方案组成需要的物品数量的背包。
分析:一个经典的多重背包问题。每一个物品按原价出售也可以看成是一种优惠方案,因此一共有N+M种优惠方案,然后用这N+M种优惠方案组成需要的物品数量的背包。
五维DP,这道题想倒是不难想,就是在对于这种关系的处理上不太容易理请思路。
program shopping;
const
maxn=5;
maxm=999;
maxt=99;
var
n,m:longint;
f:array [0..maxn,0..maxn,0..maxn,0..maxn,0..maxn] of longint;
yuanjia,need:array [0..maxn] of longint;
duiying:array [0..maxm] of longint;{duiying[i]表示编号为i的物品的对应序号。}
val:array [0..maxt*2] of longint;
cheapness:array [0..maxt,0..maxn] of longint;{cheapness[i,j]表示第i种优惠方案需要j号物品多少件。这里j号物品是需要物品中的j号物品。}
procedure init;
var
i,j,x,t:longint;
s:ansistring;
begin
assign(input,'shopping.in'); reset(input);
readln(n);
for i:=1 to n do readln(s);
readln(m);
for i:=1 to m do
begin
readln(x,need[i],yuanjia[i]);
duiying[x]:=i;
end;
close(input);{先读入一遍,以确定需要的j号物品对应的序号。}
assign(input,'shopping.in'); reset(input);
readln(n);
for i:=1 to n do
begin
read(x);
for j:=1 to x do
begin
read(t);
read(cheapness[i,duiying[t]]);
end;
readln(val[i]);
end;
for i:=n+1 to n+m do
begin
cheapness[i,i-n]:=1;
val[i]:=yuanjia[i-n];
end;
close(input);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure main;
var
i,j,k,l,ii,i1:longint;
begin
fillchar(f,sizeof(f),100);
f[0,0,0,0,0]:=0;
for i:=0 to need[1] do
begin
for j:=0 to need[2] do
begin
for k:=0 to need[3] do
begin
for l:=0 to need[4] do
begin
for ii:=0 to need[5] do
begin
for i1:=1 to n+m do
begin
if (i-cheapness[i1,1]>=0) and (j-cheapness[i1,2]>=0) and (k-cheapness[i1,3]>=0) and (l-cheapness[i1,4]>=0) and (ii-cheapness[i1,5]>=0) then
begin
f[i,j,k,l,ii]:=min(f[i,j,k,l,ii],f[i-cheapness[i1,1],j-cheapness[i1,2],k-cheapness[i1,3],l-cheapness[i1,4],ii-cheapness[i1,5]]+val[i1]);
end;
end;
end;
end;
end;
end;
end;
end;
begin
assign(output,'shopping.out'); rewrite(output);
init;
main;
writeln(f[need[1],need[2],need[3],need[4],need[5]]);
close(output);
end.