C++动态规划 求换取指定数额钱币的最少货币数 普通动态规划和空间压缩方法

本文通过C++代码介绍了如何使用动态规划算法解决寻找换取指定金额最少硬币数的问题,分别展示了普通动态规划和空间压缩两种方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>


const int max = 65535;
int minCoins(int arr[], int aim, int length);
int minCoinsPro(int arr[], int aim, int length);


int main()
{
int arr[7] = { 5, 2, 5, 3, 4, 5, 7};
int aim = 31;
int length = std::end(arr) - std::begin(arr);


std::cout << minCoins(arr, aim, length) << std::endl;
std::cout << minCoinsPro(arr, aim, length) << std::endl;




system("pause");
return 0;
}


int minCoins(int arr[], int aim, int length)
{
if (arr == nullptr || aim < 0 || length < 0)
{
return -1;
}


int sum = 0;
int **pArr = new int*[length]; //动态生成二维数组
for (int i = 0; i < length; ++i)
{
pArr[i] = new int[aim + 1];
}


for (int i = 0; i < length; ++i) //初始化第一列
{
pArr[i][0] = 0;
}
for (int i = 1; i < aim + 1; ++i) //初始化第一行
{
pArr[0][i] = max;
}
if (aim >= arr[0])
{
pArr[0][arr[0]] = 1;
}


//for (int i = 1; i < length; ++i) //构造dp数组
//{
// for (int j = 1; j < aim + 1; ++j)
// {
// if (j - arr[i] >= 0 && pArr[i - 1][j - arr[i]] != max) // 数组左上角某个值存在
// {
// pArr[i][j] = pArr[i - 1][j] <= (pArr[i - 1][j - arr[i]] + 1) ? pArr[i - 1][j] : (pArr[i - 1][j - arr[i]] + 1);
// }
// else if (pArr[i - 1][j] != max) //dp数组上一行同一列某个数存在
// pArr[i][j] = pArr[i - 1][j];
// else
// pArr[i][j] = max;
// }
//}
int left = 0;
for (int i = 1; i < length; ++i)
{
for (int j = 0; j < aim + 1; ++j)
{
left = max;
if (j - arr[i] >= 0 && pArr[i - 1][j - arr[i]] != max)
{
left = pArr[i - 1][j - arr[i]] + 1;
}
pArr[i][j] = left <= pArr[i - 1][j] ? left : pArr[i - 1][j];
}
}


sum = pArr[length - 1][aim] == max ? -1 : pArr[length - 1][aim];


for (int i = 0; i < length; ++i)
{
delete[] pArr[i];
}
delete[] pArr;


return sum;
}


int minCoinsPro(int arr[], int aim, int length)
{
if (arr == nullptr || aim < 0 || length < 0)
{
return -1;
}


int sum = 0;
int *pArr = new int[aim + 1];
pArr[0] = 0;
for (int i = 1; i < aim + 1; ++i)
{
pArr[i] = max;
}


if (aim >= arr[0])
{
pArr[arr[0]] = 1;
}


int left = 0;
for (int i = 1; i < length; ++i)
{
for (int j = aim; j >= 0; --j)
{
left = max;
if (j - arr[i] >= 0 && pArr[j - arr[i]] != max)
{
left = pArr[j - arr[i]] + 1;
}
pArr[j] = left < pArr[j] ? left : pArr[j];
}
}


sum = pArr[aim] == max ? -1 : pArr[aim];
delete[] pArr;
return sum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值