C++动态规划 求换取指定数额钱币的最少货币数 普通动态规划和空间压缩方法
2017-08-28 13:58
253 查看
#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[ai
4000
m] == max ? -1 : pArr[aim];
delete[] pArr;
return sum;
}
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[ai
4000
m] == max ? -1 : pArr[aim];
delete[] pArr;
return sum;
}
相关文章推荐
- 动态规划之换钱的最少货币数以及换钱方法数
- PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
- 动态规划及空间压缩 ,串的模式匹配(KMP) Implement strStr()(leetcode)
- ACM动态规划之最少钱币问题
- 动态规划之换钱的最少货币数
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
- 状态压缩动态规划 -- 多米诺骨牌
- hdu1074(集合上的动态规划 状态压缩)
- Tar打包、压缩与解压缩到指定目录的方法
- 【总结】120826线性动态规划的方法和优化
- 【BZOJ2004】公交线路(动态规划,状态压缩,矩阵快速幂)
- Android:指定分辨率和清晰度的图片压缩方法源码
- iOS开发之image图片压缩及压缩成指定大小的两种方法
- 动态规划 最长上升(下降)子序列 SDNUOJ 1040 导弹拦截和最少拦截系统
- Tar打包、压缩与解压缩到指定目录的方法
- 动态规划-图像压缩问题
- Pieces(hdu4628,状态压缩的动态规划)
- 动态规划:HDU1248-钱币兑换问题
- 终于找到一个方法可以使用EF的时候动态指定数据库路径了
- 求解斐波那契数列的动态规划方法