📣 独立日限时特惠: VIP通行证立减$68
查看: 3174| 回复: 5
跳转到指定楼层
上一主题 下一主题
收起左侧

找零钱算法

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
现在有大量的1元,2元,5元,10元,20元和50元面额的纸币,给定一个金额总数,用这些零钱找开,求一共多少种找法。比如4元有 :1111, 211, 22, 三种找法

有一种快的算法和一种慢的算法

上一篇:Google : 求柱状统计图里最大矩形面积
下一篇:区间最大值问题
🔗
Jawley 2011-6-5 11:50:19 | 只看该作者
全局:
这貌似跟走楼梯那个算法是差不多的,不过我不记得怎么算得了。。汗
回复

使用道具 举报

🔗
darksteel 2011-6-6 12:16:59 | 只看该作者
全局:
应该可以用类似背包问题的DP方法,只不过由于数目不确定需要稍微有点变化
回复

使用道具 举报

🔗
ForeverYoung 2011-6-7 03:36:56 | 只看该作者
全局:
Dp 或者回溯 clrs里讲过
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-6-7 12:55:53 | 只看该作者
全局:
Dp 或者回溯 clrs里讲过
ForeverYoung 发表于 2011-6-7 03:36



    所跌死捏~~~
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-6-8 20:33:00 | 只看该作者
全局:
//Two Solution:
//one is direct search, exponential time complexity, sort like NPC

//Another is dynamic programming, typical pseudo DP for NPC problem, equation:
//F(x,y) = f(x, y-1) + f(x-v(y), y-1) + f(x-2v(y), y-1) + ... + f(x-s*v(y), y-1), ((s+1)*v(y) > x)
//x is the amount of money, v(y) is the value of the change coin, y is the index

int WaysOfChange1(int nMoney, int a[], int n)
{
        assert(nMoney >= 0 && n >= 0);
        assert(a);

        if (0 == nMoney) return 1;
        if (0 == n) return 0;

        int nRet = 0;
        int nCur = 0;
        while (nCur*a[0] <= nMoney)
        {
                nRet += WaysOfChange1(nMoney-nCur*a[0], a+1, n-1);
                nCur++;
        }

        return nRet;
}

int WaysOfChange2(int nMoney, int a[], int n)
{
        assert(nMoney > 0 && a && n > 0);

        sort(a, a+n);
        int** pDP = new int* [nMoney];
        for (int i = 0; i < nMoney; i++)
                pDP[i] = new int[n];

        //init
        for (int i = 0; i < nMoney; i++)
                pDP[i][0] = ((i+1)%a[0]) == 0 ? 1 : 0;
        for (int i = 0; i < n; i++)
                pDP[0][i] = (1%a[i]) == 0 ? 1 : 0;

        //F(x,y) = f(x, y-1) + f(x-v(y), y-1) + f(x-2v(y), y-1) + ... + f(x-s*v(y), y-1), ((s+1)*v(y) > x)
        for (int i = 1; i < nMoney; i++)
                for (int j = 1; j < n; j++)
                {
                        int nVal = 0;
                        int nCur = 0;
                        while (nCur*a[j] <= i+1)
                        {
                                if (nCur*a[j] == i+1)
                                        nVal += 1;
                                else
                                        nVal += pDP[i-nCur*a[j]][j-1];

                                nCur++;
                        }
                        pDP[i][j] = nVal;
                }

        int nRet = pDP[nMoney-1][n-1];
        for (int i = 0; i < nMoney; i++)
                delete []pDP[i];
        delete []pDP;

        return nRet;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表