zoukankan      html  css  js  c++  java
  • Java实现币值最大化问题

    1 问题描述
    给定一排n个硬币,其面值均为正整数c1,c2,…,cn,这些整数并不一定两两不同。请问如何选择硬币,使得在其原始位置互不相邻的条件下,所选硬币的总金额最大。

    2 解决方案
    2.1 动态规划法

    本文所写代码思想参考自《算法设计与分析基础》第三版上一段讲解,具体如下:

    在这里插入图片描述

    在这里插入图片描述

    package com.liuzhen.chapter8;
    
    import java.util.ArrayList;
    
    public class CoinRow {
        /*
         * 参数Money:给定硬币组合面值数
         * 函数功能:以数组链表形式返回最大总金额硬币组合的数组下标以及最大总金额,
         * 其中链表中最后一个元素为最大总金额,其它元素为硬币组合数组下标
         */
        public ArrayList<Integer> getMaxSumCoin(int[] Money){
            ArrayList<Integer> list = new ArrayList<Integer>();
            if(Money.length == 1){             //当给定硬币个数只有一个时,最大总金额即为该枚硬币
                list.add(0);                   //存放硬币位置
                list.add(Money[0]);            //存放硬币总金额
                return list;
            }
            
            int[] tempMaxSum = new int[Money.length];     //用于存放遍历到当前硬币位置(从前到后遍历)的最大总金额
            tempMaxSum[0] = Money[0];
            if(Money[0] < Money[1])
                tempMaxSum[1] = Money[1];
            else
                tempMaxSum[1] = Money[0];
            
            for(int i = 2;i < Money.length;i++){
                if(tempMaxSum[i-1] >= tempMaxSum[i-2] + Money[i])
                    tempMaxSum[i] = tempMaxSum[i-1];
                else
                    tempMaxSum[i] = tempMaxSum[i-2] + Money[i];
            }
            
            System.out.println("
    当前位置硬币的最大金额:");
            for(int i = 0;i < Money.length;i++)
                System.out.print(tempMaxSum[i]+" ");
            //根据tempMaxSum数组元素,找出,最大金额的硬币组合元素的数组下标
            for(int i = Money.length-2;i >=0;i--){
                int temp = tempMaxSum[i];
                if(temp < tempMaxSum[i+1]){
                    list.add(i+1);             //存放最大金额硬币组合元素数组下标
                    temp = tempMaxSum[i+1] - Money[i+1];
                    for(int j = 0;j < Money.length;j++){   //寻找到tempMaxSum数组(从小到大排序)中第一个等于temp值的元素
                        if(tempMaxSum[j] == temp){
                            i = j;
                            break;
                        }
                    }
                }
            }
            if(Money[0] >= Money[1])      //不管怎样选择硬币组合,在前两枚硬币中一定会选一枚
                list.add(0);
            else
                list.add(1);
            list.add(tempMaxSum[Money.length-1]);     //存放硬币最大总金额
            return list;
        }
        
        public static void main(String[] args){
            CoinRow test = new CoinRow();
            int[] Money = {1,1,2,10,6,2,10,8,12};
            
            System.out.println("当前位置硬币的金额:");
            for(int i = 0;i < Money.length;i++)
                System.out.print(Money[i]+" ");
            
            ArrayList<Integer> list = test.getMaxSumCoin(Money);
            
            System.out.println("
    最大总金额硬币组合的数组下标依次为:");
            for(int i = 0;i < list.size()-1;i++)
                System.out.print(list.get(i)+" ");
            
            System.out.println("
    最大总金额硬币组合的对象数组下标相应面值依次为:");
            for(int i = 0;i < list.size()-1;i++)
                System.out.print(Money[list.get(i)]+" ");
            
            System.out.println("
    "+"最大总金额为:");
            System.out.println(list.get(list.size()-1));
        }
    }
    

    运行结果:

    当前位置硬币的金额:
    1 2 10 6 2 10 8 12 
    当前位置硬币的最大金额:
    1 3 11 11 13 21 21 33 
    最大总金额硬币组合的数组下标依次为:
    6 3 0 
    最大总金额硬币组合的对象数组下标相应面值依次为:
    10 10 1 
    最大总金额为:
    
  • 相关阅读:
    学习 Web 开发技术的16个最佳教程网站和博客
    将会改变未来IT世界的十种编程语言
    用来理解 Java 编程语言的 8 个图表
    花样Android ProgressBar
    Android控件TextProgressBar进度条上显文字
    ViewFlipper 在同一背景下 页面左右滑动
    Android自定义进度条-带文本(文字进度)的水平进度条(ProgressBar)
    android用户界面之GridView教程实例汇总
    禁止ScrollView在子控件的布局改变时自动滚动的的方法
    ListView中使用自定义Adapter及时更xin
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12948034.html
Copyright © 2011-2022 走看看