描述
有n种硬币,面值为别为a[1],a[2],a[3]……a[n],每种都有无限多。给定非负整数s,可以选取多少个硬币使得面值和恰好为s?输出硬币数目最小值和最大值
输入格式
第1行n
第2行s
第3到n+2行为n种不同的面值
第2行s
第3到n+2行为n种不同的面值
输出格式
第1行为最小值
第2行为最大值
----------------------------------------------------------------------------------------------------------------------
本题属于DAG模型的经典例题,将每个面值看成1个点,用s表示还需要凑足的面值,所以初始状态为s,目标状态为0
需要注意的是:本题属于有固定终点的DAG题
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
#define maxd 10005
int a[maxd],mina[maxd],maxa[maxd];
int main(){
int n,s;
scanf("%d%d",&n,&s);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
mina[0]=0;maxa[0]=0;
for(int i=1;i<=s;i++){
mina[i]=1<<30; //求最短路需要把每个值初始化为较大的数,以便下面min的比较
maxa[i]=-(1<<30); //同理
}
for(int i=1;i<=s;i++) //求出还需 i 面值时的最短路
for(int j=0;j<n;j++)
if(i>=a[j]){
maxa[i]=max(maxa[i],maxa[i-a[j]]+1);
mina[i]=min(mina[i],mina[i-a[j]]+1);
}
printf("%d\n%d\n",mina[s],maxa[s]);
return 0;
}