硬币问题(字典最小序)-DAG动态规划问题



题目:

     有n种硬币,面值分别为V1,V2,...Vn,每种都有无限多。给定非负整数S,可以选用多少个硬币,使得面值之和恰好为S?输出硬币数目的最小值和最大值!

   

分析:我们把每种面值看作一个点!表示“还需要凑足的面值”,初始状态为S,目标状态为0。那么若当前状态在i,每使用一个硬币j,状态便转移到i-Vj

因为求最大值跟求最小值类似,这里只贴记忆化搜索求最小值代码


代码: 下面dp1跟dp2功能相同。

不同dp2好理解一些。通过设置数组vis,标识是否访问过。牺牲空间换取效率,易读性。

<span style="font-size:24px;">#include"stdio.h"
#include"stdlib.h"
#include"algorithm"
#include"string.h"
#include"math.h"
using namespace std;
const int INF=1e9; 
const int max_coin=105;
const int max_S=10005;
int coin[max_coin];
int d[max_S]; 
int vis[max_S];
int n;
//d(i)  从节点i出发到节点0的最长路径 
int dp1(int S)
{
	//if(S==0)  return 0;
	int &ans=d[S];
	if(ans!=-1)  return ans; //记忆化搜索
	ans=INF;
	for(int i=0;i<n;i++) 
	{
		if(S>=coin[i])  
		  ans=min(ans,dp1(S-coin[i])+1);
	}
	ans=ans&#
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值