博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1742 Coins(多重背包) DP
阅读量:6089 次
发布时间:2019-06-20

本文共 1107 字,大约阅读时间需要 3 分钟。

 参考:

题意:给你n种面值的硬币,面值为a1...an,数量分别为c1...cn,求问,在这些硬币的组合下,能够多少种面值,该面值不超过m

 

思路:设d[i][j]——前i种硬币,凑成总值j时,第i种硬币所剩余的个数。

   默认d[i][j] = -1,代表无法凑成总值j

   转移方程为,若d[i-1][j]≥0,代表前i-1种已能够凑成j,那么就不必花费第i种硬币,所以d[i][j] = c[i]

   否则就看d[i][j-a[i]]的值,显然如果j < a[i],那么d[i][j] = -1,否则d[i][j-a[i]] ≤ 0,代表此刻第i种硬币已使用完了,所以自然d[i][j] = -1;

   否则,d[i][j] = d[i][j-a[i]]-1;

   可以看到d[i][]的值只与d[i-1][]和d[i][]有关,所以我们可以采用一维数组的形式,从而能够节省内存空间。

 

 AC代码:

#include 
#include
using namespace std;const int M = 100005;const int N = 105;int d[M];int n,a[N],c[N],m;void solve(){ memset(d, -1, sizeof(d)); d[0] = 0; for(int i = 0; i < n; i++) { for(int j = 0; j <= m; j++) { if(d[j] >= 0) d[j] = c[i]; else if(j < a[i] || d[j-a[i]]<= 0) d[j] = -1; else d[j] = d[j-a[i]]-1; } } int ans = 0; for(int i = 1; i <= m; i++) if(d[i]>=0) ans++; printf("%d\n", ans);}int main(){ //freopen("in.txt", "r", stdin); while(~scanf("%d %d", &n, &m) &&(n||m)) { for(int i = 0; i < n; i++) scanf("%d", a+i); for(int i = 0; i < n; i++) scanf("%d", c+i); solve(); } return 0;}

  

转载于:https://www.cnblogs.com/sevenun/p/5442279.html

你可能感兴趣的文章
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>
网络安全管理技术作业-SNMP实验报告
查看>>
根据Uri获取文件的绝对路径
查看>>
Flutter 插件开发:以微信SDK为例
查看>>
.NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理?...
查看>>
边缘控制平面Ambassador全解读
查看>>
Windows Phone 7 利用计时器DispatcherTimer创建时钟
查看>>
程序员最喜爱的12个Android应用开发框架二(转)
查看>>
vim学习与理解
查看>>
DIRECTSHOW在VS2005中PVOID64问题和配置问题
查看>>
MapReduce的模式,算法以及用例
查看>>
《Advanced Linux Programming》读书笔记(1)
查看>>
zabbix agent item
查看>>
一步一步学习SignalR进行实时通信_7_非代理
查看>>
字符设备与块设备的区别
查看>>
为什么我弃用GNOME转向KDE(2)
查看>>