你有面值为1 5 10 25 50的硬币,给定金钱n要求换的的硬币数最少,问最少的硬币的数目是多少。
比较简单就直接写式子了,dp的式子为 m【i】=min{m【i】,m[i-t[j]]+1}
代码为
#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
const int N=100005;
typedef long long ll ;
int date[N];
#define swap(a,b) {int t=a;a=b;b=t;}
const int mn=251;
const int va=5;
int t[va]={1,5,10,25,50};
int m[mn];
void so()
{
for(int k=0;k<mn;k++)
m[k]=99999;
m[0]=0;
for(int j=0;j<va;j++)
for(int i=t[j];i<mn;i++)
m[i]=min(m[i],m[i-t[j]]+1);
}
int main()
{
int s;
so();
while(cin>>s)
{
cout<<m[s]<<endl;
}
return 0;
}
如果还要输出最后硬币的组合情况,则需要把最后一枚硬币记录下来,然后向前找即可。
#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
const int N=100005;
typedef long long ll ;
int date[N];
#define swap(a,b) {int t=a;a=b;b=t;}
const int mn=251;
const int va=5;
int t[va]={1,5,10,25,50};
int m[mn];
int mp[mn]={0};
void so()
{
for(int k=0;k<mn;k++)
m[k]=99999;
m[0]=0;
for(int j=0;j<va;j++)
for(int i=t[j];i<mn;i++)
{
if(m[i]>m[i-t[j]]+1)
{
mp[i]=t[j];
m[i]=m[i-t[j]]+1;
}
}
}
void ans(int *mp,int s)
{
while(s)
{
cout<<mp[s]<<" ";
s=s-mp[s];
}
}
int main()
{
int s;
so();
while(cin>>s)
{
cout<<m[s]<<endl;
ans(mp,s);
}
return 0;
}
若是求所有的组合
把dp式子改为dp[i]+=dp[i-t[j]] 即可