数据结构&算法-动态规划

概念

动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。
问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。

运行结果

在这里插入图片描述

代码

using System;

namespace DynamicProgramming
{
    class Program
    {
        static void Main(string[] args)
        {
            DynamicProg dynamicProg = new DynamicProg();
            int minnum = -1;
            int[,] cominfo = dynamicProg.MinCom(new int[3] { 2, 5, 7 }, 50, ref minnum);
            for (int i = cominfo.GetLength(0) - 1; i > 0 && i != int.MaxValue; i = cominfo[i, 1])
            {
                Console.WriteLine(cominfo[i, 0]);
            }
            Console.WriteLine("最小使用数量:" + minnum);
            Console.ReadKey();
        }
    }


    class DynamicProg
    {
        //有三种砝码,重量分别是2g,5g,和7g,每种砝码都足够多,称一个重27g的物体,如何用最少的砝码组合正好称得27g。
        public int[,] MinCom(int[] grop, int total, ref int minnum)
        {
            int[,] indexs = new int[total + 1, 2];//用于存储 每种重量下,最小组合时, 最后一枚的重量以及前面的重量。
            int[] f = new int[total + 1]; //初始化 组合出index额度的,最小数量.
            f[0] = 0;//关键初始化界限,组合额度为0的情况,所需的数量也为0.
            indexs[0, 1] = int.MaxValue;
            indexs[0, 0] = int.MaxValue;
            for (int i = 1; i <= total; i++) //额度从1 - total。
            {
                f[i] = int.MaxValue;//起初所需的数量都是无穷大
                indexs[i, 0] = int.MaxValue;
                indexs[i, 1] = int.MaxValue;
                for (int j = 0; j < grop.Length; j++)
                {
                    if (i - grop[j] >= 0 && f[i - grop[j]] != int.MaxValue)
                    {
                        if (f[i] > f[i - grop[j]] + 1)
                        {
                            indexs[i, 0] = grop[j];//存储最后一枚的重量
                            indexs[i, 1] = i - grop[j];//存储该总重的情况下,前置重量情况
                        }
                        f[i] = Math.Min(f[i], f[i - grop[j]] + 1); //存储最小枚数
                    }
                }
            }

            if (f[total] == int.MaxValue)
            {
                minnum = -1;
            }
            else
            {
                minnum = f[total];
            }

            return indexs;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值