栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

动态规划-322零钱兑换

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态规划-322零钱兑换

  翻了半天没找到c++的记忆化搜索,我在纠结记忆数据的数组是作为共享变量,还是作为参数一直在函数中传递。

  首先我想在函数外定义个vector,然后在函数内resize大小并赋值,可以免除help在递归函数中传递,但是失败了。后来我尝试了int *help;在函数内new空间,但是也失败了。怎么办呢?没有完成我想的那样,但是下面的也可以通过题解。,,,,直接递归超时了。

1递归
    int coinChange(vector& coins, int amount) {
        if(amount==0) return 0;
        if(amount<0)  return -1;
        int res=amount+1;
        for(int coin:coins){
            int subproblem= coinChange(coins,amount-coin);
            if(subproblem==-1){
                continue;;
            }
            res=min(res,subproblem+1);
        }
        return res==amount+1?-1:res;//避免res并没有赋值,还传回去amount+1

    }
2记忆化递归
class Solution {
public:
    int coinChange(vector& coins, int amount) {
        int *help=new int[amount+1]; //记忆数组
        fill (help,help+amount+1,-2);//赋值-2,代表该amount的结点还没有获得
        sort(coins.begin(), coins.end());//将coins排序,后续可以加一下优化
        return dp(coins,amount,help);
    }

    int dp(vector& coins, int amount,int help[]) {

        if(amount==0) return 0;  //凑成0需要0个。。。
        if(amount<0) return -1;  //凑成负的不可能的,给个-1
        if(help[amount]!=-2) return help[amount];  //记忆数组里已经有了,直接用
        int res=amount+1; //amount+1是不可能超过的个数

        for (int c:coins){
            int subproblem= dp(coins,amount-c,help); //树形往下走
            if(subproblem==-1){  //负的不可能的,不进行计数
                continue;
            }

            res= min(res,subproblem+1); //通过coins.size次比较,获取兄弟几个最少用的个数
                                        //+1是因为从兄弟到他们的父节点还要加1,即amount-c的那一步
        }

        return  help[amount] = (res == amount+1) ? -1 : res; //res == amount+1避免已经到最下结点

    }
};
3自底向上循环
    int coinChange(vector& coins, int amount) {
        vector help(amount+1,amount+1); //有个base0,所以amount+1,仍然赋值不可能的数
        help[0]=0;
        for(int i=0;i<=amount;i++){ //状态:从0开始一个一个自底向上开始获取
            for(int coin:coins){ //选择:硬币金额
                if((i-coin)<0) continue;//小于0,不可能凑出
                help[i]=min(help[i],help[i-coin]+1);  
                **//其实,help[i]=min((coins,i-coin1),(coins,i-coin2),(coins,i-coin5))+1**
            }
        }
        if (help[amount] == amount + 1)
            return -1;
        //如果可以凑出,就直接返回最终值即可
        return help[amount];

    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/923686.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号