POJ 1742 Coins ( 经典多重部分和问题 DP || 多重背包 )

题意 : 有 n 种面额的硬币,给出各种面额硬币的数量和和面额数,求最多能搭配出几种不超过 m 的金额?

 

分析 :

这题可用多重背包来解,但这里不讨论这种做法。

如果之前有接触过背包DP的可以自然想到DP数组的定义 ==> dp[i][j] 表示使用前 i 种硬币是否可以凑成面额 j 。

根据这样的定义,则一开始初始化 dp[0][0] = true 最后统计 dp[n][1 ~ m] 为 true 的数量即为答案

状态转移方程为 dp[i][j] |= dp[i-1][ j - k*val[i] ] ( k 表示取 k 个第 i 种硬币、val[i] 表示第 i 种硬币的面额 )

转移方程的意义不难理解,需要考虑当前的 dp[i][j] 可以从哪些状态转移而来,如下

使用第 i 种硬币刚好凑成 j 的值应当为上个状态( dp[i-1][] )合法的 j-val[i]、j-2*val[i]、j-3*val[i]....

故代码应当为一个如下所示的三重循环,但是复杂度较高无法通过这题.....

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 111;bool dp[maxn][100005];
int num[maxn], val[maxn];int main(void)
{int N, C;while(~scanf("%d %d", &N, &C) && !(N==0 && C==0)){for(int i=1; i<=N; i++) scanf("%d", &val[i]);for(int i=1; i<=N; i++) scanf("%d", &num[i]);memset(dp, false, sizeof(dp));dp[0][0] = true;for(int i=1; i<=N; i++){for(int j=0; j<=C; j++){for(int k=0; k<=num[i] && k*val[i]<=j; k++){dp[i][j] |= dp[i-1][j-k*val[i]];}}}printf("%d\n", count(dp[N]+1, dp[N]+C+1, true));}return 0;
}
View Code

 

通常使用 dp 数组只记录布尔值是种浪费的做法,一般就去考虑在保证正确性的情况下改变 dp 含义记录更多信息去降低复杂度!

现将 dp 含义改变为 ==> dp[i][j] 表示用前 i 种硬币凑成 j 时第 i 种硬币最多还可以剩多少

挑战书上是直接给出了定义,但是我更乐于探寻这玩意是什么来的? 注:以下都是我自己的想法

想想上面的解法,好像会发现其实如果我当前考虑过 dp[i][j] = true 了,那么 dp[i][j+val[i]]、dp[i][j+2*val[i]]、dp[i][j+3*val[i]]... 应该都为 true 

而枚举 j 的顺序也恰好是从小到大,所以必定会枚举到 dp[i][j+val[i]]、dp[i][j+2*val[i]]...,所以何不写成如下这样

for(int i=1; i<=N; i++){for(int j=0; j<=C; j++){dp[j] |= dp[j-val[i]];}
}

运行了样例之后发现这样的做法得出的答案比标准答案更大!为什么?因为这样的做法没有考虑到数量,一种硬币的数量是有限的

所以当 j+k*val[i] 的 k 超过了规定数量的时候就会发生错误,使得一些本该为 false 的 dp 数组值变成了 true,所以我们需要记录数量!

复杂度为 O(n*m) 在 POJ 上跑了 2016MS

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 111;int dp[100005];
int num[maxn], val[maxn];bool fun(int x)
{ if(x>=0) return true; return false; }int main(void)
{int N, C;while(~scanf("%d %d", &N, &C) && !(N==0 && C==0)){for(int i=1; i<=N; i++) scanf("%d", &val[i]);for(int i=1; i<=N; i++) scanf("%d", &num[i]);memset(dp, -1, sizeof(dp));dp[0] = 0;for(int i=1; i<=N; i++){for(int j=0; j<=C; j++){if(dp[j] >= 0) dp[j] = num[i];else if(j < val[i] || dp[j-val[i]] <= 0) dp[j] = -1;else dp[j] = dp[j-val[i]] - 1;}}printf("%d\n", count_if(dp+1, dp+1+C, fun));}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/LiHior/p/8053149.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java nextintln_java – 从lambda表达式引用的局部变量必须是final或者有效的final

我有一个JavaFX 8程序(适用于JavaFXPorts交叉平台),它实际上是为了做我想做的事情,但却是一步之遥.程序读取文本文件,对行进行计数以建立随机范围,从该范围中选取一个随机数并读取该行以进行显示.The error is: local variables referenced from a lambda expression must be f…

css用hover制作下拉菜单

首先我们的需求就是 制作一个鼠标移动到某个区域就会有下拉菜单的弹出,这样会有更多的子类内容,示例代码如下: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>*{mar…

java链式调用空指针_java 链式调用

前言现在很多开源库或者代码都会使用链式调用。因为链式调用在很多时候&#xff0c;都可以使我们的代码更加简洁易懂。以下Student类有多数个属性&#xff0c;让我们看看非链式调用和链式调用有何区别。非链式调用Main类&#xff1a;/*** Created by chenxuxu on 17-1-10.*/pub…

mysql 字典索引_【大白话mysql】你真的了解 mysql 索引吗?

本文来源于公众号&#xff1a; 跬步匠心什么是索引&#xff1f;当我们使用汉语字典查找某个字时&#xff0c;我们会先通过拼音目录查到那个字所在的页码&#xff0c;然后直接翻到字典的那一页&#xff0c;找到我们要查的字&#xff0c;通过拼音目录查找比我们拿起字典从头一页一…

java菜单面板设置完能关闭_用Java创建一个屏幕外框架(或者:当所有应用程序窗口关闭时,如何避免Mac上的空白菜单)?...

你一定要考虑WizardOfOdds非常有用的答案.正确使用“The Application Menu”将有所帮助,并且很容易设置最小的Info.plist开始.持久的文件菜单将允许您的应用程序在其他人关闭时打开一个新窗口.这个answer链接到一个简单的example.虽然Apple的Human Interface Guidelines是您用户…

mysql使用jtable_jtable 的简单使用

做后台管理管理系统时&#xff0c;基于ajax的数据操作和富有表现力的数据绑定插件jtable绝对是一个不错的选择&#xff0c;他接收来自服务器端的json格式的数据。而且他是一款开源的基于jquery和jquery ui的插件&#xff0c;您可以根据自己的需要修改其表现&#xff0c;如css&a…

java正则表达 w_正则表达式[\s\S] 与[\w\W]这样的用法,比较.

更新时间&#xff1a;2020年03月04日 17:29:41 投稿&#xff1a;mdxy-dxy很多人咨询[\s\S]*与[\w\W]* 什么意思&#xff0c;不是有.了吗&#xff0c;那么它们的组合&#xff0c;表示所有的都匹配&#xff0c;与它相对应的&#xff0c;有[\w\W]等&#xff0c;意义完全相同,需要…

dalvik虚拟机与Java区别_05 Android---java虚拟机跟dalvik虚拟机的区别(从01开始点点入门,视频+笔记)...

大家好,我是森森这节课我简单给大家介绍一下java虚拟机跟安卓系统虚拟机的区别.可能时间太晚了,有点不在状态,也有点紧张,大家见谅.05java虚拟机跟dalvik虚拟机的区别这篇文章重点写一写安卓运行时和Java运行时的区别.什么是运行时呢?其实我们所说的虚拟机就是运行时.两种虚拟…

java自定义菜单跳转页面_微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解...

微信公众号开发 自定义菜单请先读完本文再进行配置开发请先前往微信平台开发者文档阅读“网页授权获取用户基本信息”的接口说明在微信公众账号开发中&#xff0c;往往有定义一个菜单&#xff0c;然后用户点击该菜单就进入用户个人中心的功能&#xff0c;通常应用于各个公众账号…

团队项目冲刺第一阶段03

回顾昨天:用了各种FQ软件下载SDK&#xff0c;最后终于在11点半后成功加载出helloworld 今天的任务:学习安卓数据库&#xff0c;实现对数据库信息的添加转载于:https://www.cnblogs.com/cairsha/p/8084694.html

java 解析xls 文件_java简单解析xls文件的方法示例【读取和写入】

本文实例讲述了java简单解析xls文件的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;读取&#xff1a;import java.io.*;import jxl.*;import jxl.write.*;import jxl.format.*;class Aa{public static void main(String args[]) {try{Workbook workbook null;t…

$(document).ready()和window.onload之间的差异

最近使用$(document).ready(function(){})遇到一个问题&#xff1a;加载页面后发送数据请求后台&#xff0c;得到的数据不对&#xff0c;后发现请求后台时&#xff0c;发送的数据为空&#xff0c;没有获取到值导致的。------改成window.onload function(){}或者$(window).load…

用java做出长方体的表面积_计算长方体、四棱锥的表面积和体积(Java)acm.sdut...

Problem Description计算如下立体图形的表面积和体积。从图中观察&#xff0c;可抽取其共同属性到父类Rect中&#xff1a;长度&#xff1a;l 宽度&#xff1a;h 高度&#xff1a;z在父类Rect中&#xff0c;定义求底面周长的方法length( )和底面积的方法area( )。定义父类Rect…

贝叶斯理论基础理解

从贝叶斯方法谈到贝叶斯网络&#xff1a; http://blog.csdn.net/zdy0_2004/article/details/41096141 1 思考模式 比如往台球桌上扔一个球&#xff0c;这个球落会落在何处呢&#xff1f;如果是不偏不倚的把球抛出去&#xff0c;那么此球落在台球桌上的任一位置都有着相同的机…

java mongodb 关闭连接_如何在mongodb上使用java驱动程序保持连接池关闭?

我正在从java驱动程序2.12.3升级到3.3.0.奇怪的是,收集池似乎突然“起作用”.我的设置如下&#xff1a;Connection在主线程中建立&#xff1a;mongoClient new MongoClient(new MongoClientURI("mongodb://localhost:27017"));mongoClient.setWriteConcern(new Writ…

再论递归

再论递归 大概是从汉诺塔hanoi了解递归算法的&#xff1a; function hanoi(n, a, b, c) {if(n1) {console.log(${a} ---> ${c})return}hanoi(n-1, a, c, b);hanoi(1, a, b, c);hanoi(n-1, b, a, c); }hanoi(10, A, B, C); 我自诩脑回路清奇&#xff0c;然而面对这层层递归&a…

flock lock ex php,php – flock有可能用LOCK_EX返回false吗?

标签&#xff1a;phpBy default, this function will block until the requested lock isacquired在下面我发现了以下示例代码&#xff1a;$fp fopen("/tmp/lock.txt", "r");if (flock($fp, LOCK_EX)) { // acquire an exclusive lockftruncate($fp, 0); …

C++如何实现DNS域名解析转

C如何实现DNS域名解析 这片文章介绍了C如何实现DNS域名解析&#xff0c;还有对相关技术的介绍&#xff0c;代码很详细,需要的朋友可以参考下一、概述 现在来搞定DNS域名解析&#xff0c;其实这是前面一篇文章C实现Ping里面的遗留问题&#xff0c;要干的活是ping的过程中画红线的…

PHP程序中时间戳,php 时间戳常用代码

echo strtotime(date(Y-m-d));获取明天凌晨的时间戳代码&#xff1a;echo strtotime(date(Y-m-d,strtotime(1 day)));附上测试代码&#xff1a;echo strtotime(2012-11-2);echo strtotime(2012-11-2 00:00:00);echo strtotime(date(Y-m-d)),;echo date(Y-m-d H:i:s,strtotime(d…

Echarts入门

引用Echarts 方法1&#xff1a;下载echarts.js后&#xff0c;进行引用&#xff0c;如 <script src"echarts.min.js"></script> 方法2&#xff1a;在线引用&#xff0c;在线网址可为 http://echarts.baidu.com/dist/echarts.min.js R语言中有相应的R包…