硬币问题(DAG上的动态规划)

本文探讨了一种硬币问题,其中包含不同面值的无限硬币,目标是找出达到特定非负整数s所需的硬币数量的最小值和最大值。问题被形式化为DAG(有向无环图)路径问题,从初始状态0到目标状态0,通过每次选择硬币来改变状态。文章提供了相关代码实现,包括递归解法,着重于最长路径的计算。
摘要由CSDN通过智能技术生成

问题描述:

有n种硬币,面值分别为v1,v2,v3...vn,每种硬币有无限多,给定非负整数s,可以选用多少个硬币,使得面值之和恰好为s?输出硬币数目的最小值和最大值,并且输出各自的选取方案(如果有多种方案,则输出硬币编号字典序较小的方案,输出每种选取方案的面值)。

 

分析:本质上市一个DAG上的路径问题,我们把每种面值看做一个点,表示还需凑足的面值,则初始状态为0,目标状态为0,若当前在i,则每使用一枚硬币j,状态转移到i-vj。

代码:

#include<stdio.h>
#define N 1100
int v[N],min[N],max[N],min_coins[N],max_coins[N];

void print_ans(int *d,int s, int n) {
	while(s){
		printf("%d ",v[d[s]]);
		s-=v[d[s]];
	}
	printf("\n");
}
int main() {
	int T,i,j,n,s;
	scanf("%d",&T);
	while(T--) {
		scanf("%d %d",&n,&s);
		for(i=0;i<n;i++)
			scanf("%d",&v[i]);
		min[0]=max[0]=0;
		for(i=1;i<=s;i++){
			min[i]=0x7FFFFFFF;
			max[i]=-0x7FFFFFFF;
		}
		for(i=1;i<=s;i++){
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值