目录

1 问题描述

2 解决方案

2.1 动态规划法

 


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 1 2 10 6 2 10 8 12
当前位置硬币的最大金额:
1 1 3 11 11 13 21 21 33
最大总金额硬币组合的数组下标依次为:
8 6 3 0
最大总金额硬币组合的对象数组下标相应面值依次为:
12 10 10 1
最大总金额为:
33

算法笔记_045:币值最大化问题(Java)的更多相关文章

  1. 算法笔记_023:拓扑排序(Java)

    目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进 ...

  2. 算法笔记_228:信用卡号校验(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证 ...

  3. 算法笔记_138:稳定婚姻问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 何为稳定婚姻问题? 有一个男士的集合Y = {m1,m2,m3...,mn}和一个女士的计划X = {n1,n2,n3,...,nn}.每一个男士有 ...

  4. 算法笔记_137:二分图的最大匹配(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 何为二分图的最大匹配问题? 引用自百度百科: 首先得说明一下何为匹配: 给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于 ...

  5. 算法笔记_132:最大流量问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 何为最大流量问题? 给定一个有向图,并为每一个顶点设定编号为0~n,现在求取从顶点0(PS:也可以称为源点)到顶点n(PS:也可以称为汇点)后,顶点 ...

  6. 算法笔记_040:二进制幂(Java)

    目录 1 问题描述 2 解决方案 2.1 从左至右二进制幂 2.2 从右至左二进制幂   1 问题描述 使用n的二进制表示,计算a的n次方. 2 解决方案 2.1 从左至右二进制幂 此方法计算a的n次 ...

  7. 算法笔记_014:合并排序(Java)

    1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...

  8. 算法笔记_233:二阶魔方旋转(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 魔方可以对它的6个面自由旋转. 我们来操作一个2阶魔方(如图1所示): 为了描述方便,我们为它建立了坐标系. 各个面的初始状态如下:x轴正向:绿x轴 ...

  9. 算法笔记_227:填写乘法算式(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 观察下面的算式: * * × * * = * * * 它表示:两个两位数字相乘,结果是3位数.其中的星号(*)代表任意的数字,可以相同,也可以不同, ...

随机推荐

  1. 数据离散化 ( 以及 stl 中的 unique( ) 的用法 )+ bzoj3289:Mato的文件管理

    http://blog.csdn.net/gokou_ruri/article/details/7723378 ↑惯例Mark大神的博客   bzoj3289:Mato的文件管理 线段树求逆序对+莫队 ...

  2. 【BFS】【map】hdu5925 Coconuts

    题意:一张n*m的网格图(n和m可以达到10^9),其中K个点是障碍物(不超过200个),问你没有被障碍物占据的点形成了几个连通块?并且输出各个连通块的大小. 容易证明,大小超过40000的连通块最多 ...

  3. bzoj 3931: [CQOI2015]网络吞吐量 -- 最短路+网络流

    3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MB Description 路由是指通过计算机网络把信息从源地址传输到目的地址 ...

  4. MyBatis 错误日志检索

    当怀疑是sql语句执行存在错误时,可以用一下关键字检索日志文件: 检索关键字: Cause: SQLException sql原始报错内容: [DEBUG] [2016-05-03 09:37:05 ...

  5. 擦亮自己的眼睛去看SQLServer之谈谈锁机制

    http://www.cnblogs.com/yueyue_jwfm/category/292724.html

  6. 使用 JMeter 完成常用的压力测试

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  7. Andriod for arcgis 字段属性

    Feature pFeature = selFeatureLayer.getFeature(8); Log.d("FID===", "" + pFeature. ...

  8. qt 中文乱码 处理QByteArray类型里含中文的数据

    qt解析tcp通信传来的xml时,中文有乱码 解决方法: 头文件加入 #include <QTextCodec> QByteArray tmpQBA = m_pSocket->rea ...

  9. boa cgi程序cgi_header: unable to find LFLF

    ftp必须用二进制模式上传才可以 sqlite3 arm-linux-gcc hello.c -o hello.cgi -I /cgi/include -L /cgi/lib -static -lsq ...

  10. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...