【编程之法】换硬币问题

此解法参考:
python27 的博客(http://www.cnblogs.com/python27/p/3303721.html)

#include
#include
#include
using namespace std;

const int maxn = 10;    // 硬币用类数最大值
const int maxsum = 1000;// 要兑换的钱数的最大值

/**
*   dp[i][j] : 使用 i 中硬币 兑换 j 元钱的组合的种类数
*   xi : 第 i 种硬币使用的个数
    if xi == 0 then dp[i][j] += dp[i-1][j]
    if xi == 1 then dp[i][j] += dp[i-1][j-xi*vi] vi 表示 第 i 种硬币的面额
    until
    xi == j / vi then 最后求和之后的 dp[i][j] 即为使用 i 种硬币兑换 sum 元钱的组合的种类数
    则递推公式为 --> dp[i][j] = dp[i-1][j] + dp[i-1][j-vi] + ··· + dp[i-1][j-(j/vi)*vi];
    最后要求的及为 dp[n][sum]
    其中dp[i][0] = 1;  i = 0,1,2,3,...,maxn       --> 使用任意种硬币兑换 0 元 都是只有 1 种方法
    dp[0][sum] = 0;    sum = 1,2,3,...,maxsum     --> 只用0种硬币兑换任何钱都是 0 种方法
*
*/
int dp[maxn][maxsum] = {0}; // dp[i][j] : 使用 i 中硬币 兑换 j 元钱的种类数


int main()
{
    int sum;            // 想兑换的总金额
    int n;              // 存储硬币的种类个数
    vector<int> v;      // 存储不同硬币的面额
    int tmp;            // 临时变量

    v.push_back(0);     // 不使用 vector 的 0 号下标

    cin >> sum;
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        cin >> tmp;
        v.push_back(tmp);
    }

    // begin
    dp[0][0] = 1;               // 使用 0 种硬币兑换 0 元的方法 有 1 种   --> 起始点
    for(int i = 1; i <= n; ++i) // 从 1 种 硬币开始,0种硬币已经初始化完成
    {
        for(int j = 0; j <= sum; ++j)
        {
            if(j == 0)
            {
                dp[i][j] = 1;
            }
            else
            {
                dp[i][j] = 0;
                // xi 遍历 0-j/vi
                for(int xi = 0; xi <= j/v[i]; ++xi)
                {
                    dp[i][j] += dp[i-1][j-(xi*v[i])];
                }
            }
        }
    }
    // end

    cout << dp[n][sum];

    return 0;
}

样例输入
100
4
1 2 5 10

样例输出
2156

你可能感兴趣的:(学习笔记)