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

问题描述:

有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、付费专栏及课程。

余额充值