算法初探-动态规划(Dynamic Programming)

本文探讨了硬币组合问题及数塔问题的算法解决方案。通过动态规划方法,解决了如何使用最少数量的1、3、5元硬币组合成11元的问题,并给出了一般化的解决思路。同时,介绍了数塔问题的状态转移方程及其求解过程。

编程之中接触到很多关于算法的知识,想来整理一番,算是对自己记忆的一个提醒


1.Coin11Problem  问题为:使用最少的三种面值为1,3,5的硬币组合出11元。


重要的是状态以及状态转移方程 d(i)=min{ d(i-vj)+1 },其中i-vj >=0,vj表示第j个硬币的面值;



package com.njit.dynamic_programming;

/**
 * 使用最少若干的1,3,5硬币,组合出11元
 *  
 * @author  邵鹏
 * @version  [V1.00, 2017年7月13日]
 * @see  [相关类/方法]
 * @since V1.00
 */
public class Coin11Problem
{
    public static void main(String[] args)
    {
        //状态以及状态转移方程
        //d(i)     d(i)=min{d(i-vj)+1}   vj为硬币的值
        int[] a ={1,3,5};
        int[] dp =new int[12];
        dp[0]=0;
        for(int i=1;i<=11;i++){
            dp[i]=i;
        }
        for(int i=1;i<=11;i++){
            for(int j=0;j<3;j++){
                if(i>=a[j] && dp[i-a[j]]+1<dp[i]){
                    dp[i]=dp[i-a[j]]+1;
                }
            }
        }
        System.out.println("最少需要"+dp[11]+"个硬币可以组成11");
//        System.out.println(a[0]+" "+a[1]+" "+a[2]);
        for(int i=1;i<=11;i++){
            System.out.print(dp[i]+" ");
        }
        
    }
    
    
    
}


以上为特定11元

以下为推广

package com.njit.dynamic_programming;

public class Coin11ProblemCommonVersion
{
    public static void main(String[] args)
    {
        //调用方法 在1 3 5 三个硬币中找出最少的组合方式 组成 sum 变量为输入的sum
        int inputCoin=11;
        int outputCoin= new Coin11ProblemCommonVersion().getMinCoin(inputCoin);
        System.out.println("当总数为 "+inputCoin+" 时,最少的硬币数为:"+outputCoin);
        
        int[] outputCoinArray =new Coin11ProblemCommonVersion().getMinCoinArray(inputCoin);
        System.out.println("当总数为 "+inputCoin+" 时,各硬币数为:");
        for(int i=1;i<=inputCoin;i++){
            System.out.println("dp["+i+"]="+outputCoinArray[i]);
        }
        
    }
    
    
    /** 
     * 根据输入,动态输出硬币数量
     * 
     * @param sum
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int getMinCoin(int sum){
        int coin=0;
        int[] a ={1,3,5};
        int[] dp = new int[sum+1];
        dp[0]=0;
        for(int i=1;i<=sum;i++){
            dp[i]=i;
        }
        for(int i=1;i<=sum;i++){
            for(int j=0;j<3;j++){
                if(i>=a[j] && dp[i-a[j]]+1<dp[i] ){
                    dp[i]=dp[i-a[j]]+1;
                }
            }
        }
        
        return dp[sum];
    }
    
    /** 
     * 输入最后的硬币数,返回过程中的所有最小硬币数
     * <功能详细描述>
     * @param sum
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int[] getMinCoinArray(int sum){
        int coin=0;
        int[] a ={1,3,5};
        int[] dp = new int[sum+1];
        dp[0]=0;
        for(int i=1;i<=sum;i++){
            dp[i]=i;
        }
        for(int i=1;i<=sum;i++){
            for(int j=0;j<3;j++){
                if(i>=a[j] && dp[i-a[j]]+1<dp[i] ){
                    dp[i]=dp[i-a[j]]+1;
                }
            }
        }
        return dp;
    }
    
}

2.MathTowerProblem (数塔问题:三角形结构,算出从下到上,数字总和最大的一条路径的和)

状态转移方程

f[i][j] = max(f[i+1][j], f[i+1][j+1]) + map[i][j]

        int[][] mathTower = new int[][]{{0,0,0,0,0,0},{0,7,0,0,0,0},{0,3,8,0,0,0},
            {0,8,1,0,0,0},{0,2,7,4,4,0},{0,4,5,2,6,5}};
        System.out.println("原始节点为:");
        for(int i=1;i<=5;i++){
            for(int j=1;j<=i;j++){
                System.out.print(mathTower[i][j]+" ");
            }
            System.out.println();
        }
        
        for(int i=5;i<=5;i--){
            for(int j=1;j<i;j++){
                mathTower[i-1][j]+=Math.max(mathTower[i][j], mathTower[i][j+1]);
            }
        }
        System.out.println("自底而上的最大数值路径得到的值为: "+mathTower[1][1]);
        for(int k=1;k<=5;k++){
            for(int t=1;t<=k;t++){
                System.out.print(" "+mathTower[k][t]);
            }
            System.out.println();
        }





【激光质量检测】利用丝杆与步进电机的组合装置带动光源的移动,完成对光源使用切片法测量其光束质量的目的研究(Matlab代码实现)内容概要:本文研究了利用丝杆与步进电机的组合装置带动光源移动,结合切片法实现对激光光源光束质量的精确测量方法,并提供了基于Matlab的代码实现方案。该系统通过机械装置精确控制光源位置,采集不同截面的光强分布数据,进而分析光束的聚焦特性、发散角、光斑尺寸等关键质量参数,适用于高精度光学检测场景。研究重点在于硬件控制与图像处理算法的协同设计,实现了自动化、高重复性的光束质量评估流程。; 适合人群:具备一定光学基础知识和Matlab编程能力的科研人员或工程技术人员,尤其适合从事激光应用、光电检测、精密仪器开发等相关领域的研究生及研发工程师。; 使用场景及目标:①实现对连续或脉冲激光器输出光束的质量评估;②为激光加工、医疗激光、通信激光等应用场景提供可靠的光束分析手段;③通过Matlab仿真与实际控制对接,验证切片法测量方案的有效性与精度。; 阅读建议:建议读者结合机械控制原理与光学测量理论同步理解文档内容,重点关注步进电机控制逻辑与切片数据处理算法的衔接部分,实际应用时需校准装置并优化采样间距以提高测量精度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值