Dp:
题1,凑硬币:
如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
状态转移方程:d(i)=min{d(i-vj)+1 },其中i-vj >=0,vj表示第j个硬币的面值;
i 最小硬币数 取得硬币面值(上一级的i)
比如,从上面的图我们可以看出,最终结果d(11)=d(10)+1(面值为1),而d(10)=d(5)+1(面值为5),最后d(5)=d(0)+1 (面值为5)。所以我们凑够11元最少需要的3枚硬币是:1元、5元、5元。
///不需找面值
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int w[10]={0,1,3,5};
int dp[100],n,book[100];
int money[100];
dp[0]=0; ///此位置需初始化为0
while(~ scanf("%d",&n))
{
for(int i=1;i<=n;i++)
dp[i]=9999;
for(int i=1;i<=n;i++) ///凑够i元至少需要几枚硬币
{
for(int j=1;w[j]<=i;j++) ///表示w[j]小于当前i元,进行dp
{
dp[i]=min(dp[i],dp[i-w[j]]+1);
}
}
printf("%d\n",dp[n]);
}
return 0;
}
找挑的面值为
///需找面值
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int w[10]={0,1,3,5};
int dp[100],n,book[100];
int money[100];
dp[0]=0; ///此位置需初始化为0
while(~ scanf("%d",&n))
{
for(int i=1;i<=n;i++)
dp[i]=9999;
for(int i=1;i<=n;i++) ///凑够i元至少需要几枚硬币
{
for(int j=1;w[j]<=i;j++) ///表示w[i]小于当前i元,进行dp
{
// dp[i]=min(dp[i],dp[i-w[j]]+1);
if(dp[i]>dp[i-w[j]]+1){
dp[i]=dp[i-w[j]]+1;
book[i]=i-w[j]; ///标记找出凑得硬币的面值,表示当前的上一个要找的i-w[i],
}
}
}
printf("%d\n",dp[n]);
///假设要找凑够n元需要硬币的面值是
while(n)
{
printf("%d ",n-book[n]); ///将当前可用的钱数减去book[n](上一级可用的钱数)
n=book[n];
}
}
return 0;
}