usaco 3.3 shopping 2008.11.7

usaco 3.3 shopping 2008.11.7

注意:1.物品的编号,不一定就是按照物品的输入顺序来的,一定要另开一个数组存储!

     2.这个程序用到了重复读入文件,先读过不要的东西,读入下面的东西后,再重新开文件读入先前跳过的东西

     3.要初始化为不用优惠的应用多少钱

算法: 0 <= b <= 5,1 <= k<= 5,可用5*5*5*5*5的DP 每种买0~5个,可以用6进制表示,然后5维DP~OK!

状态设置F[a1][a2][a3][a4][a5]为买a1件物品1,a2件物品2,a3件物品3,a4件物品4,a5件物品5时,所需的最少价格

边界条件:F[0][0][0][0][0]=0;初始化f[][][][][]不用优惠时应用的钱数

状态转移方程:

F[a1][a2][a3][a4][a5]=min{F[ a1-P[i][1] ][ a2-P[i][2] ][a3-P[i][3] ][ a4-P[i][4] ][ a5-P[i][5] ]+P[i][0])}

其中i=1..s+b; 且 ak-p[i][k]>=0

{

ID: HP226261

PROG: shopping

LANG: PASCAL

}

program shopping;
var
  hao{唯一编号},cast{直接购买的花费}:array[1..5] of integer;
  mm{某物品要买多少}:array[1..5] of byte;
  y{优惠价格}:array[1..100] of integer;
  f:array[0..5,0..5,0..5,0..5,0..5] of integer;
  z{优惠方式}:array[1..100,1..5] of integer;
  i,j,m,n,k,b,s,xx,yy,i1,i2,i3,i4,i5:integer;
  key{这个优惠会不会买到不用买的东西}:array[1..100] of boolean;
 
function w(nk:integer):byte;{计算NK编号是第几号商品}
var
  i:integer;
begin
  for i:=1 to b do if nk=hao[i] then exit(i);
  w:=0;{不用买这个商品}
end;
begin
assign(input,'shopping.in');
reset(input);
assign(output,'shopping.out');
rewrite(output);
  readln(m);
  for i:=1 to m do readln;{跳过优惠方式的读取先}
  readln(b);
  for i:=1 to b do readln(hao[i],mm[i],cast[i]);
reset(input);{回到文件开头读取优惠方式}
  readln(m);
  for i:=1 to m do
  begin
    read(n);
    for j:=1 to n do begin
      read(xx,yy);
      xx:=w(xx);
      if xx=0 then key[i]:=true;{这种优惠不能用……}
      if not key[i] then z[i,xx]:=yy;
    end;
    readln(y[i]);
  end;
 
 
//初始化为不用优惠时的购买价格
  for i1:=0 to mm[1] do
    for i2:=0 to mm[2] do
      for i3:=0 to mm[3] do
        for i4:=0 to mm[4] do
          for i5:=0 to mm[5] do
            f[i1,i2,i3,i4,i5]:=i1*cast[1]+i2*cast[2]+i3*cast[3]+i4*cast[4]+i5*cast[5];
//初始化完了
  for i:=1 to m do
  if not key[i] then
    for i1:=z[i,1] to mm[1] do
      for i2:=z[i,2] to mm[2] do
        for i3:=z[i,3] to mm[3] do
          for i4:=z[i,4] to mm[4] do
            for i5:=z[i,5] to mm[5] do
              if f[i1,i2,i3,i4,i5]>f[i1-z[i,1],i2-z[i,2],i3-z[i,3],i4-z[i,4],i5-z[i,5]]+y[i] then
                f[i1,i2,i3,i4,i5]:=f[i1-z[i,1],i2-z[i,2],i3-z[i,3],i4-z[i,4],i5-z[i,5]]+y[i];
  writeln(f[mm[1],mm[2],mm[3],mm[4],mm[5]]);
close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值