HDOJ2844-Coins(DP)
来源:互联网 发布:linux acl 编辑:程序博客网 时间:2024/06/06 02:28
题意:你有n种面值的硬币,告诉你每种硬币的数量,问这些硬币能拼成多少不超过m的面额。
思路:多重背包。当某种硬币的总额大于背包容量时进行完全背包,否则进行二进制拆分进行01背包。最后统计f[i]==i的数量,即恰好能凑出金额为i的情况总数。详解请参考背包九讲。
代码如下:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int f[100010];int v[105],s[105];//面值,数量int max(int x,int y){ return x>y?x:y;}void work(int n,int m){ int i,j,k,t,ans; memset(f,0,sizeof(f)); for(i=0;i<n;i++) scanf("%d",&v[i]); for(i=0;i<n;i++) scanf("%d",&s[i]); for(i=0;i<n;i++) { if(v[i]*s[i]>=m) { //若某种金币的总金额大于总价,则直接进行完全背包 for(j=v[i];j<=m;j++) f[j]=max(f[j],f[j-v[i]]+v[i]); } else { k=1; while(k<s[i]) { //将物品进行二进制拆分,进行01背包操作 for(j=m;j>=v[i]*k;j--) f[j]=max(f[j],f[j-v[i]*k]+v[i]*k); s[i]-=k; k<<=1; } //对二进制拆分后剩下的物品进行01背包 for(j=m;j>=v[i]*s[i];j--) f[j]=max(f[j],f[j-v[i]*s[i]]+v[i]*s[i]); } } ans=0; for(i=1;i<=m;i++) ans+=(f[i]==i); printf("%d\n",ans);}int main(){ int n,m; while(scanf("%d%d",&n,&m),n||m) work(n,m); return 0;}
0 0
- HDOJ2844-Coins(DP)
- POJ1742 Coins DP
- dividing coins 简单dp
- hdu 2844 Coins dp
- POJ 1742 Coins (DP)
- poj 1742 Coins(dp)
- hdu 2844 Coins DP
- HDU_2844 Coins(DP)
- dp(uva562Dividing coins)
- dp(good)uva10306e-Coins
- hdu 2844 Coins dp
- POJ_1742 Coins(DP)
- [POJ1742 Coins]DP
- Coins(背包DP)
- hdu2844 Coins(DP)
- poj 1742 coins dp
- HDU Coins(dp)
- HDU 2448 Coins dp
- Android TextView行间距解析
- matlab spdiags函数语法
- 图像拼接的基本流程及关键技术
- YARN Container 启动流程分析
- zoj 3879 Capture the Flag(模拟 数学)
- HDOJ2844-Coins(DP)
- Java知识(008)--面向对象入门
- 一篇关于营销的功能需求分析
- POJ 2986 A Triangle and a Circle
- java解惑--令人混淆的构造器案例
- #pragma once 和#define比较
- UVa10491 - Cows and Cars(概率)
- C++ primer 读书笔记(第1章)开始
- Python IDLE