• [HAOI2008]硬币购物


    1042: [HAOI2008]硬币购物

    时间限制: 10 Sec  内存限制: 162 MB
    提交: 2057  解决: 1209

    题目描述

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

    输入

      第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000

    输出

      每次的方法数

    样例输入

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

    样例输出

    4
    27
    题解:
      这个题是dp + 容斥。
      首先可以预处理dp[i]表示在四种硬币没有限制的情况下买i的东西有几种付款方式。
      然后就可以容斥了:
      根据容斥原理,答案为 得到面值S的超过限制的方案数 – 第1种硬币超过限制的方案数 – 第2种硬币超过限制的方案数 – 第3种硬币超过限制的方案数 – 第4种硬币超过限制的方案数 + 第1,2种硬币同时超过限制的方案数 + 第1,3种硬币同时超过限制的方案数 + …… + 第1,2,3,4种硬币全部同时超过限制的方案数。
      讲解一下上边公式的来历, 这题所要求的数值为4种硬币在有限个情况下的方案数, 在dp数组中, 我们求得的数值为4种硬币在无限个情况下的方案数。
      则 有限个的方案数(即所求) = 无限个的方案数 - 超过有限个的方案数。
      利用容斥原理求出超过有限个的方案数。
      一种硬币时的求法:固定取w[i] + 1个, 剩下的随便取就好。
    #include <iostream>
    #define MAX 100001
    #define ll long long
    
    using namespace std;
    
    int c[5], w[5];
    ll dp[MAX], ans;
    
    void DFS(int x, int k, int sum)
    {
        if(sum < 0) return;
        if(x == 5)
        {
            if(k & 1) ans = ans - dp[sum];
            else ans = ans + dp[sum];
            return;
        }
        DFS(x + 1, k + 1, sum - (w[x] + 1) * c[x]);
        DFS(x + 1, k, sum);
    }
    
    int main()
    {
        int tot, s;
        for(int i = 1; i <= 4; ++i) 
            cin >> c[i];
        cin >> tot;
        dp[0] = 1;
        for(int i = 1; i <= 4; ++i)
            for(int j = c[i]; j < MAX; ++j)
                dp[j] = dp[j] + dp[j - c[i]];
        for(int i = 1; i <= tot; ++i)
        {
            for(int ii = 1; ii <= 4; ++ii)
                cin >> w[ii];
            cin >> s;
            ans = 0;
            DFS(1, 0, s);
            cout << ans << endl;
        }
        return 0;
    }
    Sugar
  • 相关阅读:
    HashMap实现原理
    框架-Spring
    团队开发介绍
    返回一个环状整数数组中最大子数组之和
    软件工程学习体会
    书店促销
    寻找小水王
    梦断代码阅读笔记3
    找水王
    梦断代码阅读笔记2
  • 原文地址:https://www.cnblogs.com/without-sugar/p/5865114.html
Copyright © 2020-2023  润新知