BZOJ1042: [HAOI2008]硬币购物

1042: [HAOI2008]硬币购物

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1005  Solved: 585
[Submit][Status]

Description

硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

Input

第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s

Output

每次的方法数

Sample Input

1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900

Sample Output

4
27
数据规模
di,s<=100000
tot<=1000

HINT

 

Source

题解:https://www.byvoid.com/blog/haoi-2008-coin

神一般的容斥原理+补集转化!

谨防数组越界。。。lazarus什么都不报,fpc数据一大就卡爆了。。。

代码:

{$inline on}
const maxn=100000+1000;
var i,j,n,m:longint;
    f:array[0..maxn] of int64;
    ans,t1,t2,t3,t4:int64;
    c:array[1..4] of int64;
procedure init;
 begin
   readln(c[1],c[2],c[3],c[4],n);
 end;
function g(x:int64):int64;inline;
 begin
   if x>=0 then exit(f[x]);
   exit(0);
 end;

procedure main;
 begin
   f[0]:=1;
   for i:=1 to 4 do
    for j:=1 to maxn do
     inc(f[j],g(j-c[i]));
   //for i:=0 to maxn do writeln(i,' ',f[i]);
   for i:=1 to n do
    begin
      readln(t1,t2,t3,t4,m);
      ans:=f[m];
      t1:=(t1+1)*c[1];t2:=(t2+1)*c[2];t3:=(t3+1)*c[3];t4:=(t4+1)*c[4];
      //dec(ans,g(m-t1));dec(ans,g(m-t2));dec(ans,g(m-t3));dec(ans,g(m-t4));
      //dec(ans,g(m-t1-t2-t3));dec(ans,g(m-t1-t2-t4));dec(ans,g(m-t1-t3-t4));dec(ans,g(m-t2-t3-t4));
      //inc(ans,g(m-t1-t2));inc(ans,g(m-t1-t3));inc(ans,g(m-t1-t4));inc(ans,g(m-t2-t3));inc(ans,g(m-t2-t4));inc(ans,g(m-t3-t4));
      //inc(ans,g(m-t1-t2-t3-t4));
      dec(ans,g(m-t1)+g(m-t2)+g(m-t3)+g(m-t4));
      dec(ans,g(m-t1-t2-t3)+g(m-t1-t2-t4)+g(m-t1-t3-t4)+g(m-t2-t3-t4));
      inc(ans,g(m-t1-t2)+g(m-t1-t3)+g(m-t1-t4)+g(m-t2-t3)+g(m-t2-t4)+g(m-t3-t4));
      inc(ans,g(m-t1-t2-t3-t4));
      writeln(ans);
    end;
 end;

begin
  assign(input,'input.txt');assign(output,'output.txt');
  reset(input);rewrite(output);
  init;
  main;
  close(input);close(output);
end.     

 

posted @ 2014-08-14 23:35  ZYF-ZYF  Views(396)  Comments(0Edit  收藏  举报