五大算法之动态规划法

 定义:

要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 

题目一:

钢条根据不同长度切割,卖的价格也不同,价格表如下,假设一条10米长的钢条要怎么切割才能保证收益最大?

长度12345678910
价格1589101717202430

using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour {

    private void Main() {


        int[] priceArray = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };//索引表示钢条的长度,值表示价格
        int[] haveArray = new int[11];

        print(DynamicProgramming(5, priceArray,haveArray));
    }

    /// <summary>
    /// 动态规划
    /// </summary>
    /// <param name="n"></param>
    /// <returns></returns>
    private int DynamicProgramming(int n, int[] priceArray, int[] haveArray) {

        int max = 0;
        int temp = 0;
        for (int i = 1; i < n + 1; i++)
        {
            for (int j = 1; j < i + 1; j++)
            {
                temp = priceArray[j] + haveArray[i - j];
                if (temp > max)
                {
                    max = temp;
                }
            }

            haveArray[i] = max;
        }

        return max;
    }

}

题目二:

假设有容量为m的背包,另外有i个物品(每种物品只有1个),每个物品有重量和价值去,求怎么这个背包最大能放的价值是多?

物品ABCD
重量3478
价值2346

using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour {

    private void Main() {

        int[] weightArray = { 3, 4, 7, 8 };  //重量
        int[] priceArray = { 2, 3, 4, 6 };   //价值

        print(DynamicProgramming(7, weightArray, priceArray));

    }

    /// <summary>
    /// 动态规划
    /// </summary>
    /// <param name="n"></param>
    /// <returns></returns>
    private int DynamicProgramming(int weight, int[] weightArray, int[] priceArray) {

        int[,] haveArray = new int[weight + 1, weightArray.Length];

        for (int i = 1; i < weight + 1; i++)
        {
            for (int j = 0; j < weightArray.Length; j++)
            {
                int lastValue = 0;
                if (j != 0)
                {
                    lastValue = haveArray[i, j - 1];
                }

                if (weightArray[j] > i)
                {
                    haveArray[i, j] = lastValue;
                }
                else
                {
                    int takeValue = 0;
                    if (j == 0)
                    {
                        takeValue = priceArray[j];
                    }
                    else
                    {
                        takeValue = priceArray[j] + haveArray[i - weightArray[j], j - 1];
                    }

                    int noTakeValue = lastValue;

                    if (takeValue > noTakeValue)
                    {
                        haveArray[i, j] = takeValue;
                    }
                    else
                    {
                        haveArray[i, j] = noTakeValue;
                    }
                }
            }

        }

        return haveArray[weight, weightArray.Length - 1];
    }

}

题目三:

一只青蛙每次可跳一个或者两个台阶,求青蛙有多少种跳到第n个台阶的方法?

using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour {

    private void Main() {

        print(DynamicProgramming(30));

    }

    /// <summary>
    /// 动态规划
    /// </summary>
    /// <param name="n"></param>
    /// <returns></returns>
    private int DynamicProgramming(int n) {

        int[] haveArray = new int[n + 1];
        haveArray[0] = 0;
        haveArray[1] = 1;
        haveArray[2] = 2;

        for (int i = 3; i < n + 1; i++)
        {
            haveArray[i] = haveArray[i - 2] + haveArray[i - 1];
        }

        return haveArray[n];

    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值