zoukankan      html  css  js  c++  java
  • UVa OJ 147 Dollars (钱币)

    Time limit: 3.000 seconds
    限时:3.000秒

    Problem
    问题

    New Zealand currency consists of $100, $50, $20, $10, and $5 notes and $2, $1, 50c, 20c, 10c and 5c coins. Write a program that will determine, for any given amount, in how many ways that amount may be made up. Changing the order of listing does not increase the count. Thus 20c may be made up in 4 ways: 1 × 20c, 2 × 10c, 10c+2 × 5c, and 4 × 5c.
    新西兰的流通货币中,纸币分为五种:100元、50元、20元、10元和5元;硬币分为六种:2元、1元、50分(即五毛)、20分、10分和5分。写一个程序计算出对于给定的任意金额,可以有多少种不同的钱币组合方式。仅仅改变顺序的不能算。比如20分可以有以下4种组合方式:1 × 20分, 2 × 10分, 10分+2 × 5分, 和4 × 5分。

    Input
    输入

    Input will consist of a series of real numbers no greater than $300.00 each on a separate line. Each amount will be valid, that is will be a multiple of 5c. The file will be terminated by a line containing zero (0.00).
    输入由一组实数构成,每个实数都不会超过300.00元,并且都独占一行。金额都是有效的,即都是5分的整数倍。输入由一行零元(0.00)表示结束。

    Output
    输出

    Output will consist of a line for each of the amounts in the input, each line consisting of the amount of money (with two decimal places and right justified in a field of width 6), followed by the number of ways in which that amount may be made up, right justified in a field of width 17.
    每行输入对应一行输出,包括总金额(保留两位小数并右对齐至第6列),后面是可以组成该金额的方法数,右对齐宽度为17。

    Sample Input
    输入示例

    0.20
    2.00
    0.00

    Sample Output
    输出示例

      0.20                4
      2.00              293

    Analysis
    分析

    此题较难,是一个子集合问题。可以用递归式直接计算任意给定金额的组合方案,但是所给的数据可能非常大,用递归的话肯定会TLE,因此必须通过递推的方式生成所有可能金额的答案,运行时直接查表即可。

    建表过程如下:首先任何金额都可仅由5分组成这1种方案,如果金额刚好等于某一种钱币,就还有这一种方案,因此10分有2种方案。15分的第一种方案可仅由5分组成,要计算由10分或5分组成(不包括前面算过的全部5分的情况)的情况,可先减掉10分(因为这种情况至少包括一个10分),剩下的5分就只有1种情况,因此共有2种方案。20分的第一种方案可由5分组成;第二种情况先减掉10分还剩10分,而10分由10分或5分组成的情况有2种,因此都要计入;最后一种方案就是直接使用20分,因此一共4种方案。其余的以此类推。

    注意到所有钱数都是5的整数倍,因此可以将货币面值和查询的金额统一除以5再计算。要注意按指定的格式输出结果,并在输入0时退出程序。

    这个思路讲起来很麻烦,如果您有更好的公式化理论敬请提出!

    Solution
    解答

    #include <iomanip>
    #include <iostream>
    using namespace std;
    int main(void) {
    	//钱币数,全部除以5
    	int Coins[] = {1, 2, 4, 10, 20, 40, 100, 200, 400, 1000, 2000};
    	long long Tbl[6001] = {1}; //各金额组合方案数总表
    	//以下开始建表,按钱币种类进行循环
    	for (int i = 0; i < 11; i++){
    		//仅使用i之前的钱币进行组合,但不包括不使用i的情况
    		for (int j = Coins[i]; j < 6001; j++) {
    			//先减掉第i种钱币,然后加上剩下的金额的组合方案数
    			Tbl[j] += Tbl[j - Coins[i]];
    		}
    	} //以下为设定格式,查表输出结果。
    	cout << fixed << showpoint << setprecision(2);
    	for (float fIn; cin >> fIn && fIn != 0; cout << endl) {
    		cout << setw(6) << fIn << setw(17) << Tbl[(int)(fIn * 20 + 0.5f)];
    	}
    	return 0;
    }
    



    知识共享许可协议 作者:王雨濛;新浪微博:@吉祥村码农;来源:《程序控》博客 -- http://www.cnblogs.com/devymex/
    此文章版权归作者所有(有特别声明的除外),转载必须注明作者及来源。您不能用于商业目的也不能修改原文内容。
  • 相关阅读:
    Django Form组件的扩展
    Python TCP与UDP的区别
    Python三次握手和四次挥手
    网络基础之网络协议
    Python 类方法、实例方法、静态方法的使用与及实例
    python深浅拷贝
    2021牛客寒假算法基础集训营1 题解
    01 Trie 专题
    MOTS:多目标跟踪和分割论文翻译
    牛客巅峰赛S2第6场题解
  • 原文地址:https://www.cnblogs.com/devymex/p/1808714.html
Copyright © 2011-2022 走看看