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 
    最大总金额为:
    
  • 相关阅读:
    Android Studio 单刷《第一行代码》系列 05 —— Fragment 基础
    Android Studio 单刷《第一行代码》系列 04 —— Activity 相关
    Android Studio 单刷《第一行代码》系列 03 —— Activity 基础
    Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat
    Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld
    IDEA 内网手动添加oracle,mysql等数据源,以及server returns invalid timezone错误配置
    eclipse maven设置
    IntelliJ IDE 常用配置
    eclipse maven 常见问题解决方案
    Maven 安装和配置
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12948034.html
Copyright © 2011-2022 走看看