求助用C# 动态规划实现一下硬币找零问题,希望能有注释,感谢!
零钱值 : 4, 10, 15
需找零值: 希望是可以自己input的任何值, (40,35等)
https://www.cnblogs.com/hapjin/p/5578852.html
C#只需要修改一个地方,length换成Count()
/**
*
* @param coinsValues 可用来找零的硬币 coinsValues.length是硬币的种类
* @param n 待找的零钱
* @return 最少硬币数目
*/
public static int charge(int[] coinsValues, int n){
int[][] c = new int[coinsValues.length + 1][n + 1];
//特殊情况1
for(int i = 0; i <= coinsValues.length; i++)
c[i][0] = 0;
for(int i = 0; i <= n; i++)
c[0][i] = Integer.MAX_VALUE;
for(int j_money = 1; j_money <=n; j_money++)
{
for(int i_coinKinds = 1; i_coinKinds <= coinsValues.length; i_coinKinds++)
{
if(j_money < coinsValues[i_coinKinds-1])//特殊情况2,coinsValues数组下标是从0开始的, c[][]数组下标是从1开始计算的
{
c[i_coinKinds][j_money] = c[i_coinKinds - 1][j_money];//只能使用 第 1...(i-1)枚中的硬币
continue;
}
//每个问题的选择数目---选其中较小的
if(c[i_coinKinds - 1][j_money] < (c[i_coinKinds][j_money - coinsValues[i_coinKinds-1]] +1))
c[i_coinKinds][j_money] = c[i_coinKinds - 1][j_money];
else
c[i_coinKinds][j_money] = c[i_coinKinds][j_money - coinsValues[i_coinKinds-1]] +1;
}
}
return c[coinsValues.length][n];
}
#include <iostream>
using namespace std;
const int M=1000;
const int N = 3;
int coint[N];
int count[M+1];//count[i]表示凑合数量为i所需最少的钱币数量,则count[i]=min{count[i-coint[j]]+1},其中0<=j<=N-1
int trace[M+1];//每个表示count[i]在取最小值时的选择,即上式中的j
int dp_count(int m)
{
int i = 0;
int j = 0;
for(i=0;i<M+1;i++)
count[i]=0xffff;
count[0] = 0;
for(i=0;i<=m;i++)
{
for(j=0;j<N;j++)
if(coint[j]<= i && count[i-coint[j]]+1 < count[i])
{
count[i] = count[i-coint[j]]+1;
trace[i] = coint[j];
}
}
return count[m];
}
void print(int m)
{
if(m==0)
return;
else
{
cout << trace[m] << " ";
print(m-trace[m]);
}
}
int main()
{
int i=0;
for(i=0;i<N;i++)
cin>>coint[i];
int m;
cin >> m;
cout<<dp_count(m)<<endl;
print(m);
}