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;
;
];
int num[maxn], val[maxn];
int main(void)
{
int N, C;
&& C==)){
; i<=N; i++) scanf("%d", &val[i]);
; i<=N; i++) scanf("%d", &num[i]);
memset(dp, false, sizeof(dp));
dp[][] = true;
; i<=N; i++){
; j<=C; j++){
; k<=num[i] && k*val[i]<=j; k++){
dp[i][j] |= dp[i-][j-k*val[i]];
}
}
}
printf(, dp[N]+C+, true));
}
;
}
通常使用 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]]...,所以何不写成如下这样
; i<=N; i++){
; 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;
;
];
int num[maxn], val[maxn];
bool fun(int x)
{ ) return true; return false; }
int main(void)
{
int N, C;
&& C==)){
; i<=N; i++) scanf("%d", &val[i]);
; i<=N; i++) scanf("%d", &num[i]);
memset(dp, -, sizeof(dp));
dp[] = ;
; i<=N; i++){
; j<=C; j++){
) dp[j] = num[i];
) dp[j] = -;
;
}
}
printf(, dp++C, fun));
}
;
}
POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )的更多相关文章
- poj 1742 Coins(二进制拆分+bitset优化多重背包)
\(Coins\) \(solution:\) 这道题很短,开门见山,很明显的告诉了读者这是一道多重背包.但是这道题的数据范围很不友好,它不允许我们直接将这一题当做01背包去做.于是我们得想一想优化. ...
- hdu 2844 poj 1742 Coins
hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正 ...
- 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- poj 1742 Coins(dp之多重背包+多次优化)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- POJ 1742 Coins(多重背包, 单调队列)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- [POJ 1742] Coins 【DP】
题目链接:POJ - 1742 题目大意 现有 n 种不同的硬币,每种的面值为 Vi ,数量为 Ni ,问使用这些硬币共能凑出 [1,m] 范围内的多少种面值. 题目分析 使用一种 O(nm) 的 D ...
- POJ 1742 Coins 【多重背包DP】
题意:有n种面额的硬币.面额.个数分别为A_i.C_i,求最多能搭配出几种不超过m的金额? 思路:dp[j]就是总数为j的价值是否已经有了这种方法,如果现在没有,那么我们就一个个硬币去尝试直到有,这种 ...
- POJ 1742 Coins(多重背包) DP
参考:http://www.hankcs.com/program/cpp/poj-1742-coins.html 题意:给你n种面值的硬币,面值为a1...an,数量分别为c1...cn,求问,在这些 ...
- poj 1742 Coins (多重背包)
http://poj.org/problem?id=1742 n个硬币,面值分别是A1...An,对应的数量分别是C1....Cn.用这些硬币组合起来能得到多少种面值不超过m的方案. 多重背包,不过这 ...
随机推荐
- back()是返回,也就是说,先加载地址到A页面,再打开页面到B页面,调用 back()方法,就返回到了A页面
from selenium import webdriverdriver=webdriver.Firefox()driver.maximize_window()driver.get('http://w ...
- 把对像生成json并存储到文件
1.创建实体对像json import com.alibaba.fastjson.annotation.JSONField; import java.util.Date; public class S ...
- 通过Spark Streaming处理交易数据
Apache Spark 是加州大学伯克利分校的 AMPLabs 开发的开源分布式轻量级通用计算框架. 由于 Spark 基于内存设计,使得它拥有比 Hadoop 更高的性能(极端情况下可以达到 10 ...
- CM使用MySQL数据库预处理scm_prepare_database.sh执行报错:java.sql.SQLException: Access denied for user 'scm'@'hadoop101.com' (using password: YES)
1.报错提示: [root@hadoop101 ~]# /opt/module/cm/cm-/share/cmf/schema/scm_prepare_database.sh mysql cm -hh ...
- C++代码审查
C++代码审查 1. 目的与要求 寻找结对编程伙伴,并练习结对编程: 对同伴的作品进行代码复审,设计审查表并填写: 评价同伴的代码,介绍同伴的优缺点. 2. 复审代码 小伙伴李宏达的项目代码与博客地址 ...
- Centos7防火墙开启3306端口
CentOS7的默认防火墙为firewall,且默认是不打开的. systemctl start firewalld # 启动friewall systemctl status firewalld # ...
- 工作笔记之:如何在eclipse安装CVS插件?找了很久的,自己总结一下
(1)在主目录里“help”→Install New Software.....→The Eclipse Project Updates - http://download.eclipse.org/e ...
- SpringMVC源码解析
一:springmvc运行过程: 1. dispatcherServlet 通过 HandlerMapping 找到controller2. controller经过后台逻辑处理得到结果集modela ...
- JS调用PageMethods
http://www.cnblogs.com/Ren_Lei/archive/2010/07/14/1777413.html JS调用PageMethods 操作步骤: 1.新建一个WebApplic ...
- Centos 修改当前路径显示为全路径
1.修改显示全路径: vim /etc/bashrc 找到[ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\ ...