您的位置:首页 > 其它

动态规划-硬币问题

2017-05-20 16:05 471 查看
问题描述:

输入总金额n,硬币不同价值的种类m,m种硬币的面值; 

例如:15 6

1 2 7 8 12 50

    输出凑成n最少的硬币数

(1)贪心算法:

每次都选择面值最大的。问题在于,求出来的并不是最优解,上例中,用贪心解出来的结果为3(1,2,12),而实际为2(7,8)

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int a[m];
for(int i=0;i<m-1;i++)
cin>>a[i];
sort(a,a+m);
int count=0;
for(int i=m-1;i>=0;)
{
if(a[i]<=n)
{
count++;
if(a[i]==n)
break;
else
n=n-a[i];
}
else i--; //每一硬币可以重复使用
}
cout<<count;
}
(2)动态规划

dp[j] 代表目标为j元的时候,需要的硬币数量

状态转移方程 dp[j+a[i]]=min(dp[j+a[i]],dp[j]+1) 代表选择当前硬币面值为a[i]时,放或者不放,找出数量最小的一个

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int a[m+1];
for(int i=1;i<=m;i++)
cin>>a[i];
sort(a,a+m);
int dp[n+1];
for(int i=0;i<n+1;i++)
dp[i]=i; //初始化
for(int i=1;i<=m;i++)
for(int j=0;j+a[i]<=n;j++)
dp[j+a[i]]=min(dp[j+a[i]],dp[j]+1);
//for(int i=1;i<=n;i++)
//cout<<dp[i]<<" ";
cout<<dp
;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: