• 1042: [HAOI2008]硬币购物


    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

    每一次都做一次多重背包跟定是不行的,这个先预处理一下,然后可以用容斥原理O(1)回答

    我们可以这样用容斥,先算出没有限制钱币数量的方案数,记为f[i],表示没有限制,总价值为i的方案数,然后减去至少一种钱币超过限制的方案数,加上至少两种钱币超过限制的方案数,减去至少三种钱币超过限制的方案数,最后加上四种钱币都超过限制的方案数,第i种钱币超过限制就是第i种钱币至少用了di+1个(例:第1种钱币超过限制的方案数就是f[s-c[1]*(d1+1)])

    犯了一个傻逼错误

    求f[i]的时候我是这么求的

    1     for i:=1 to maxs do
    2       for j:=1 to 4 do
    3         inc(f[i],fn(i-c[j]));

    然后理所当然的爆了int64

    为了不重复计算方案,所以应该以j为阶段(话说动态规划的阶段是什么早就忘了),就像这样

    1     for j:=1 to 4 do
    2       for i:=1 to maxs do
    3         inc(f[i],fn(i-c[j]));

    吐槽:

    R:容斥原理是什么?我们学过吗?

    X:学过啊

    R:额,这算学过吗,我只记得老师叫我们用容斥写在100以内是2,3,5的倍数的数有多少,然后要我们查公式,这TM有什么意思,这个题有必要做吗,换个例题不行啊

    当时我就想啊,容斥这么垃圾(不要打我......),我就直接跳过了,没想到容斥原来用处挺大的啊(当时讲的那个例题毫无吸引力好吗)

     1 const
     2     maxs=100010;
     3 var
     4     f:array[0..maxs]of int64;
     5     c:array[1..4]of longint;
     6     n:longint;
     7     ans:int64;
     8 
     9 function fn(x:longint):int64;
    10 begin
    11     if x>=0 then exit(f[x]);
    12     exit(0);
    13 end;
    14 
    15 procedure main;
    16 var
    17     i,j,d1,d2,d3,d4,s:longint;
    18 begin
    19     for i:=1 to 4 do
    20       read(c[i]);
    21     f[0]:=1;
    22     for j:=1 to 4 do
    23       for i:=1 to maxs do
    24         inc(f[i],fn(i-c[j]));
    25     read(n);
    26     for i:=1 to n do
    27       begin
    28         read(d1,d2,d3,d4,s);
    29         ans:=fn(s);
    30         dec(ans,fn(s-c[1]*(d1+1)));
    31         dec(ans,fn(s-c[2]*(d2+1)));
    32         dec(ans,fn(s-c[3]*(d3+1)));
    33         dec(ans,fn(s-c[4]*(d4+1)));
    34         inc(ans,fn(s-c[1]*(d1+1)-c[2]*(d2+1)));
    35         inc(ans,fn(s-c[1]*(d1+1)-c[3]*(d3+1)));
    36         inc(ans,fn(s-c[1]*(d1+1)-c[4]*(d4+1)));
    37         inc(ans,fn(s-c[2]*(d2+1)-c[3]*(d3+1)));
    38         inc(ans,fn(s-c[2]*(d2+1)-c[4]*(d4+1)));
    39         inc(ans,fn(s-c[3]*(d3+1)-c[4]*(d4+1)));
    40         dec(ans,fn(s-c[2]*(d2+1)-c[3]*(d3+1)-c[4]*(d4+1)));
    41         dec(ans,fn(s-c[1]*(d1+1)-c[3]*(d3+1)-c[4]*(d4+1)));
    42         dec(ans,fn(s-c[1]*(d1+1)-c[2]*(d2+1)-c[4]*(d4+1)));
    43         dec(ans,fn(s-c[1]*(d1+1)-c[2]*(d2+1)-c[3]*(d3+1)));
    44         inc(ans,fn(s-c[1]*(d1+1)-c[2]*(d2+1)-c[3]*(d3+1)-c[4]*(d4+1)));
    45         writeln(ans);
    46       end;
    47 end;
    48 
    49 begin
    50     main;
    51 end.
    View Code
  • 相关阅读:
    ZOJ 1217 eight
    COJ 1080 A simple maze
    八数码(双向广搜)
    HDOJ 1043 eight
    [HDOJ] 小兔的棋盘
    ZOJ 2110 Tempter of the Bone
    POJ 2406 Power Strings
    [HDOJ] goagain的超级数列
    COJ 1216 异或最大值
    八数码(IDA*)
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3649744.html
Copyright © 2020-2023  润新知