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("\n当前位置硬币的最大金额:");
        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("\n最大总金额硬币组合的数组下标依次为:");
        for(int i = 0;i < list.size()-1;i++)
            System.out.print(list.get(i)+" ");
        System.out.println("\n最大总金额硬币组合的对象数组下标相应面值依次为:");
        for(int i = 0;i < list.size()-1;i++)
            System.out.print(Money[list.get(i)]+" ");
        System.out.println("\n"+"最大总金额为:");
        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
最大总金额为:
												
											Java实现币值最大化问题的更多相关文章
- [C++]动态规划系列之币值最大化
		
/** * * @author Zen Johnny * @date 2018年3月31日 下午10:04:48 * */ package freeTest.dynamicProgramming; i ...
 - 算法笔记_045:币值最大化问题(Java)
		
目录 1 问题描述 2 解决方案 2.1 动态规划法 1 问题描述 给定一排n个硬币,其面值均为正整数c1,c2,...,cn,这些整数并不一定两两不同.请问如何选择硬币,使得在其原始位置互不相邻 ...
 - java selenium手动最大化chrome浏览器的方法
		
package my_automation; import java.awt.Dimension; import org.openqa.selenium.Capabilities; import or ...
 - Spark案例分析
		
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
 - 最大化 AIX 上的 Java 性能,第 5 部分: 参考资料和结论
		
http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf5.html 最大化 AIX 上的 Java 性能,第 ...
 - 最大化 AIX 上的 Java 性能,第 4 部分: 监视流量
		
http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf4.html 最大化 AIX 上的 Java 性能,第 ...
 - 最大化 AIX 上的 Java 性能,第 3 部分: 更多就是更好
		
http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf3.html 最大化 AIX 上的 Java 性能,第 ...
 - 最大化 AIX 上的 Java 性能,第 2 部分: 速度需求
		
http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf2.html 最大化 AIX 上的 Java 性能,第 ...
 - 最大化 AIX 上的 Java 性能,第 1 部分: 基础
		
http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf1.html 最大化 AIX 上的 Java 性能,第 ...
 
随机推荐
- SWPU邮件登录界面的仿写(第二次作业)
			
(一).检查并下载网页元素 在需仿写的页面按F12,点击element,寻找需要的图片元素. (二). 分析网页的布局 查看网页源代码. (三).开始仿写 由于我们的目标是仿写网页,所以可以直接复制网 ...
 - ThreadLocal 内存泄漏问题深入分析
			
写在前面 ThreadLocal 基本用法本文就不介绍了,如果有不知道的小伙伴可以先了解一下,本文只研究 ThreadLocal 内存泄漏这一问题. ThreadLocal 会发生内存泄漏吗? 先给出 ...
 - zabbix监控redis多实例cpu mem-自动发现
			
1.自动发现实例端口脚本,用于zbx item prototypes #!/bin/bash REDIS_PORT=`ps aux |grep redis-server | grep -v 'grep ...
 - fastDFS多线程并发执行出现的问题
			
--------------------- 原作者:Java高级开发 来源:CSDN 原文:https://blog.csdn.net/hang1995/article/details/7924 ...
 - package.json中^,~的区别
			
https://blog.csdn.net/peaceoncemore/article/details/79195206 "devDependencies": { " ...
 - poj1780欧拉回路
			
转载 #include<cstdio> #include<cstring> ; bool vis[N]; char ans[N]; int main() { int n; wh ...
 - Java并发编程入门(二)
			
1.竞态条件 1.1 定义 当某个计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件.换句话说,正确的结果要取决于运气. 最常见的竞态条件类型:先检查后执行(Check-Then-Act)操 ...
 - 附件1:setTimeout与闭包
			
我在详细图解作用域链与闭包一文中的结尾留下了一个关于setTimeout与循环闭包的思考题. 利用闭包,修改下面的代码,让循环输出的结果依次为1, 2, 3, 4, 5 for (var i=1; i ...
 - [安卓基础] 006.打开另一个Activity
			
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
 - [SD心灵鸡汤]010.每月一则 - 2016.02
			
1.世上只有一种英雄主义,就是在认清生活真相之后依然热爱生活. 2.要想赢,就一定不能怕输.不怕输,结果未必能赢.但是怕输,结果则一定是输. 3.你要做的就是别人换不掉的,那你做不到怪谁,就是你自己没 ...