USACO 2.3.4 Money Systems 货币系统(完全背包)
Description
母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。 [In their own rebellious way],,他们对货币的数值感到好奇。 传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。 母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。 举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它。 写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。 保证总数将会适合long long (C/C++) 和 Int64 (Free Pascal)。
Input
货币系统中货币的种类数目是 V 。 (1<= V<=25) 要构造的数量钱是 N 。 (1<= N<=10,000) 第 1 行: 二整数, V 和 N 第 2 ..V+1行: 可用的货币 V 个整数 (每行一个 每行没有其它的数)。
Output
单独的一行包含那个可能的构造的方案数。
Sample Input
3 10 1 2 5
Sample Output
10
解题思路:我上来一直觉得这是一道搜索题,用DFS写了一下,果然时间超限,其实这是一道完全背包的变形。
dp[i][j]表示前i种货币构成钱j的方法数,用a记录货币的面值,状态转移方程为:
dp[i][j]=dp[i-1][j]; ///不用第i种货币
dp[i][j]=dp[i-1][j]+dp[i][j-a[i]] ///当j>=a[i]时,用第i种货币
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MAX 10010 5 #define ll long long int 6 using namespace std; 7 int a[30]; 8 ll dp[30][MAX]; 9 int main() 10 { 11 int m,n; 12 int i,j; 13 scanf("%d%d",&n,&m); 14 for(i=1;i<=n;i++) 15 { 16 scanf("%d",&a[i]); 17 dp[i][a[i]]=1; 18 } 19 for(i=1;i<=n;i++) 20 { 21 for(j=1;j<=m;j++) 22 { 23 if(j>a[i]) 24 { 25 dp[i][j]=dp[i][j-a[i]]+dp[i-1][j]; 26 } 27 else 28 { 29 dp[i][j]=dp[i][j]+dp[i-1][j]; 30 } 31 } 32 } 33 printf("%lld\n",dp[n][m]); 34 return 0; 35 }
优化为一维滚动数组之后:
1 for(i=1;i<=n;i++) 2 { 3 scanf("%d",&a[i]); 4 } 5 dp[0]=1; 6 for(i=1;i<=n;i++) 7 { 8 for(j=a[i];j<=m;j++) 9 { 10 dp[j]=dp[j]+dp[j-a[i]]; 11 } 12 } 13 printf("%lld\n",dp[m]);
本文作者:王陸
本文链接:https://www.cnblogs.com/wkfvawl/p/9714978.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)