首页 > 其他分享 >从暴力递归到动态规划

从暴力递归到动态规划

时间:2023-04-22 21:57:00浏览次数:37  
标签:Commodity 暴力 递归 int aim start var new 动态

    /// <summary>
    /// 机器人 不停尝试
    /// </summary>
    /// <param name="start">开始位置</param>
    /// <param name="aim">要到的位置</param>
    /// <param name="n">总的数</param>
    /// <param name="k">步数</param>
    /// <returns></returns>
    public int Way1(int start,int aim,int n,int k)
    {
        if(n <= 1 || start < 1 || start > n || aim < 1 || aim > n || k <= 0){
            return -1;
        }
        return Proccess1(start, aim, n, k);
    }

    public int Proccess1(int cur,int aim,int n,int rest){
 
        if (rest == 0) return cur == aim ? 1 : 0; // 剩余步骤是0,且恰好在目标位置。
        // if(cur < 0 || cur == n) return -1; 不是0,就从1开始 ***

        if(cur == 1) return Proccess1(cur+1,aim,n,rest-1);
        if(cur == n) return Proccess1(cur-1,aim,n,rest-1);
        return Proccess1(cur+1,aim,n,rest-1) + Proccess1(cur-1,aim,n,rest-1);
    }

    /// <summary>
    /// 加缓存 可变参数决定维度 这里在递归时变化的是start,k
    /// </summary>
    /// <param name="start"></param>
    /// <param name="aim"></param>
    /// <param name="n"></param>
    /// <param name="k"></param>
    /// <returns></returns>
    public int Way2(int start,int aim,int n,int k)
    {
        if(n <= 1 || start < 1 || start > n || aim < 1 || aim > n || k <= 0){
            return -1;
        }
        int[,] dp = new int[n+1,k+1];
        for (int i = 0; i <= n; i++)
        {
            for(int j=0; j <= k; j++)
            {
                dp[i,j] = -1;
            }
        }
        return Proccess2(start, aim, n, k, dp);
    }

    // cur  [1~n]
    // rest [0~k] 
    public int Proccess2(int cur,int aim,int n,int rest,int[,] dp){
 
        if (rest == 0) return cur == aim ? 1 : 0; // 剩余步骤是0,且恰好在目标位置。
        // if(cur < 0 || cur == n) return -1; 不是0,就从1开始 ***
        // 我以为是一维数组了,还是要画图(树状图)
        /*(6,7)出现两次。有重复解
                   (6,9)
             (5,8)       (7,8)
          (4,7)  (6,7) (6,7)  (8,7)
        */

        if(dp[cur,rest] != -1) return dp[cur,rest];
        if(cur == 1) {
            dp[cur,rest] = Proccess2(cur+1,aim,n,rest-1,dp);
        }
        else if(cur == n) 
        {
            dp[cur,rest] = Proccess2(cur-1,aim,n,rest-1,dp);
        }else{
            dp[cur,rest] = Proccess2(cur+1,aim,n,rest-1,dp) + Proccess2(cur-1,aim,n,rest-1,dp);
        }
        return dp[cur,rest];
    }

    /// <summary>
    /// 动态规划 动作决定结果 填表 动态规划是结果不是原因
    /// 返回的结果是:dp[start,rest] 必须在一条线上
    /// </summary>
    /// <param name="start"></param>
    /// <param name="aim"></param>
    /// <param name="n"></param>
    /// <param name="k"></param>
    /// <returns></returns>
    public int Way3(int start,int aim,int n,int k)
    {
        if(n <= 1 || start < 1 || start > n || aim < 1 || aim > n || k <= 0){
            return -1;
        }
        int[,] dp = new int[n+1,k+1];
        // n = 4 rest = 2 start 1 aim = 3
        // 怎么填,看暴力递归 rest == 0,aim = 3(行等于3)
        // cur=1(行等于1) cur+1,rest-1 左下
        // cur=4(行等于4) cur-1,rest-1 左上
        // cur=2,3中间位置, cur-1,rest-1 + cur+1,rest-1
        /*
                0   1   2   
            0   X   X   X
            1   X   x   1
            2   X   1   x
            3   1   x   2
            4   X   1   x
        */
        dp[aim,0] = 1; // int数组本身初始化就是0
        Proccess3(start, aim, n, k, dp);
        return dp[start, k];
    }

    // cur  [1~n]
    // rest [0~k] 
    public void Proccess3(int cur,int aim,int n,int rest,int[,] dp)
    {
        // if (rest == 0) return cur == aim ? 1 : 0; // 剩余步骤是0,且恰好在目标位置。
        // 一列一列填
        for(int col=1;col<=rest;col++)
        {
            dp[1,col] = dp[2,col-1]; // 第一行
            for(int row=2;row<n;row++) // 第二行及之后
            {
                dp[row,col] = dp[row-1,col-1] + dp[row+1,col-1];
            }
            dp[n,col] = dp[n-1,col-1]; // 最后一行
        }
         
    }

--所用币种数量

    public void Test(){
        // int start,int aim,int n,int k
        // var rt = Way3(2,4,5,6);
        // var rt = Change();
        IList<Commodity> commodities = new List<Commodity>(){
            new Commodity(3,5),
            new Commodity(2,6),
            new Commodity(4,3),
            new Commodity(7,19),
            new Commodity(3,12),
            new Commodity(1,4),
            new Commodity(7,2),
        };
        int bag = 5;
        //var rt = MaxValue2(commodities,bag);
        var rt = GetMinCount();
        var rt2 = GetMinCount();
        System.Console.WriteLine($"结果是:{rt2},递归:{rt}");
        System.Console.WriteLine("33");
    }

    // coins面值
    // 返回最小张数
    /*
        是否重复计算 coins = [1,2,5] amount = 15 是存在重复计算的
                            P(0,15)
        P(1,14)                     p(1,13)         P(1,10)
      P(2,13) P(2,12) P(2,9)    P(2,12)
      2.返回值,怎么调用的
      3.怎么填值,根据尝试函数
    */

    public int GetMinCount2( )
    {
        var coins = new int[]{1,2,5};
        int n = coins.Count();
        int k = 15;
        int[,] dp = new int[n+1,k+1];
        // 
        dp[n,0] = 0;
        for(int j=1;j<=n;j++)
        {
            dp[n,j] = int.MaxValue;
        }
        for(int row = n-1;row>=0;row++)
        {
            for(int col=0;col<=k;col++)
            {
                int ans = int.MaxValue;
                // coin所需硬币数
                for (int coin = 0; coin * coins[row] <= col; coin++)
                {
                    int next = dp[col+1,col - col-coins[row]]; // GetMinCountProccess(coins,index+1,rest - coin*coins[index]);
                    if(next != int.MaxValue)
                    {
                        ans = Math.Min(ans, next + coin);
                    }
                }
                dp[row,col] =  ans;
            }
        }

        return dp[0,k];
    }
    
    // coins面值
    // 返回最小张数
    public int GetMinCount( )
    {
        var coins = new int[]{1,2,5};
        var rt = GetMinCountProccess(coins,0,15);
        return rt;
    }
    public int GetMinCountProccess(int[] coins,int index,int rest)
    {
        if(index == coins.Length)
        {
            return rest == 0 ? 0 : int.MaxValue;
        }else
        {
            int ans = int.MaxValue;
            // coin所需硬币数
            for (int coin = 0; coin * coins[index] <= rest; coin++)
            {
                int next = GetMinCountProccess(coins,index+1,rest - coin*coins[index]);
                if(next != int.MaxValue)
                {
                    ans = Math.Min(ans, next + coin);
                }
            }
            return ans;
        }
    }

 

标签:Commodity,暴力,递归,int,aim,start,var,new,动态
From: https://www.cnblogs.com/Insist-Y/p/17344166.html

相关文章

  • Django—Form两种解决表单数据无法动态刷新的方法
    一、无法动态更新数据的实例#Createyourmodelshere.classClasses(models.Model):title=models.CharField(max_length=32)def__str__(self):returnself.titleclassTeacher(models.Model):name=models.CharField(max_length=32)t2c=model......
  • vector动态数组库
    #include<vector>usingnamespacestd;vector<int>vec1;//定义一个空的vector,元素类型为intvector<int>vec2(10);//定义一个大小为10的vector,元素类型为int,初始值为0vector<int>vec3(10,1);//定义一个大小为10的vector,元素类型为int,初始值为1vector<int>vec4={1,2,......
  • Java中递归的简单应用
    递归是一种非常常见的编程技巧,它可以将一个复杂的问题分解成更小的问题,然后递归地解决这些小问题,最终得到整个问题的解。递归的本质就是函数调用自身。我们来看一个简单的例子:计算阶乘。阶乘是指将一个数和它以及它之前的所有正整数相乘的结果,通常用符号"!"表示。例如,5的阶乘就是......
  • ORCLE静态监听注册/动态监听注册
    1.什么是注册注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时......
  • 力扣——6.动态规划
    title:动态规划6、最长上升子序列(1)采用动态规划,算法复杂度为O(n*n)intlengthOfLIS(int*nums,intnumsSize){inti,j,max=1;if(NULL==nums||0==numsSize){return0;}int*dp=(int*)malloc(numsSize*sizeof(int));memset(dp,0,nu......
  • 递推与递归和DFS深度优先搜索
    递推与递归和DFS深度优先搜索跳台阶递归实现指数级枚举递归实现排列型枚举递归实现组合型枚举P1036选数习题课递推/递归/DFSP2089烤鸡指数P1088火星人全排列P1149火柴棒等式指数+预处理P2036PERKET指数P1135奇怪的电梯暴力迷宫问题P1683入门P1605......
  • 使用递归完成RBAC
     先使用ling查询将每个角色下的权限进行查询其次调用并返回这个GetFor方法,第一个参数是当前角色下的权限,第二个是权限的父ID顶级为0,GetFor方法是查询当前list集合用Printid作为条件,然后返回类型是一对多的样式所以创建dto进行赋值,然后那个集合需要反复调用这个方法来查询这......
  • threejs_动态heatmap渲染
    heatmap>heatmap2d.tsimport{Mesh,Texture,MeshBasicMaterial,PlaneGeometry,Box3,Vector3,}from'three';importBasefrom'../Base';importHeatMap,{DataPoint}from'heatmap-ts';import{log}from......
  • 【LeetCode动态规划#11】打家劫舍系列题(涉及环结构和树形DP的讨论)
    打家劫舍力扣题目链接(opensnewwindow)你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组......
  • HTML5: 利用SVG动画动态绘制文字轮廓边框线条
    DEMO:点击这里看效果 简要教程这是一款很酷的html5svg线条动态绘制文字轮廓边框动画特效。SVG路径动画在网页设计中是一项热门的技术,它允许我们绘制各种简单、精美的图标和文字。关于使用SVG制作图标方面的知识,请参考阅读ESSENTIALICONS。制作流程先......