http://uva.onlinejudge.org/external/6/674.html我正在努力解决这个问题。不过,请注意,这不是最小硬币更换问题,它要求我使用50, 25, 15, 10, 5和1美分硬币制作N美分的不同方法。它相当简单,所以我做了这个函数:
int count(int n, int m) // n is the N of the problem, m is the number of coin types and s[] is {1, 5, 10, 25, 50}
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
return DP[n][m - 1] + DP[n - s[m]][m];
}
同样简单的是添加动态编程和备忘录:
int count(int n, int m)
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
else
{
return DP[n][m - 1] + DP[n - s[m]][m];
}
}
然而,这些都不够快-我需要自下而上的动态规划,但我在编码它时遇到困难,即使在算法学家的帮助下-http://www.algorithmist.com/index.php/Coin_Change.
void generate()
{
for (i = 0; i < MAX; i++)
{
for (u = 0; u < m; u++)
{
if (i == 0)
{
DP[i][u] = 1;
}
else if (u == 0)
{
DP[i][u] = 0;
}
else if (s[u] > i)
{
DP[i][u] = DP[i][u - 1];
}
else
{
DP[i][u] = DP[i][u - 1] + DP[i - s[u]][u];
}
}
}
}
出于某种原因,我得到的每个结果都是0,这是我的完整代码:
#include <stdio.h>
#include <string.h>
using namespace std;
#define MAX 7490
int s[] = {1, 5, 10, 25, 50}, m = 5, input, DP[MAX][5], i, u;
int count(int n, int m)
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
else
{
return DP[n][m - 1] + DP[n - s[m]][m];
}
}
void generate()
{
for (i = 0; i < MAX; i++)
{
for (u = 0; u < m; u++)
{
if (i == 0)
{
DP[i][u] = 1;
}
else if (u == 0)
{
DP[i][u] = 0;
}
else if (s[u] > i)
{
DP[i][u] = DP[i][u - 1];
}
else
{
DP[i][u] = DP[i][u - 1] + DP[i - s[u]][u];
}
}
}
}
int main()
{
memset(DP, -1, sizeof DP);
generate();
while (scanf("%d", &input) != EOF)
{
//printf("%d\n", count(input, 4));
printf("%d\n", DP[input][4]);
}
return 0;
}
你在这里犯了错误:
else if (u == 0)
{
DP[i][u] = 0;
}
它应该是DP[i][u]=1
,因为你可以用1分硬币以1种可能的方式产生任何值i
。i、 e.取5美分,你将取5枚1美分的硬币,这是总共5美分的一种方式。
顺便说一句,在你的第一种计数方法中,你有以下几点:
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
或者这个:
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return DP[n][m] = count(n, m - 1) + count(n - s[m], m);
}
如果您没有将已计算的结果进行记忆,则此记忆检查如果(DP[n][m-1]=-1 | | DP[n-s[m]][m]=-1)
将永远无法工作,这可能是您的第一种方法太慢的原因:-?
我编写的代码使用动态规划解决了基本的硬币兑换问题,并给出了进行兑换所需的最小硬币数量。但是我想把每个硬币的数量存储在最小的数字里。 我试图做的是初始化数组,就像散列一样,只要找到,它就会增加的数量,即。但这并不是我想要的方式,因为它每次发现对应于时都会添加硬币。因此,在最终答案中,数字不是硬币的最终计数。 代码如下:
但是我们不能这样做吗:(是给定的可用硬币的排序集,和是它的下标,是给定的最高价值硬币) 我写的东西有什么问题吗?虽然解决方案不是动态的,但不是更有效吗?
在硬币系统C={c1,c2,…ck}中,应改变给定的数量x,以使每个硬币ci具有给定的重量wi。我们想计算可能变化的总重量。两种变化是不同的,如果他们包含在不同的顺序相同的硬币。 如何给出上述问题的动态规划递归?我知道最小硬币兑换问题的递归(即C(x)=min{C(x-C)1 for x
问题-你会得到不同面额的硬币和总金额。写一个函数来计算你需要的最少数量的硬币来组成这个数量。那里有无限的硬币供应。 我的方法——我遵循了自上而下的方法,但是使用map stl进行记忆,我得到了TLE。请帮助找出误差和估计时间复杂度。 这是我的密码-
我一直在使用动态规划研究硬币兑换问题。我尝试制作一个数组fin[],其中包含索引所需的最小硬币数,然后打印它。我已经写了一个代码,我认为应该给出正确的输出,但我不明白为什么它没有给出准确的答案。例如:对于输入:4 3 1 2 3(4是要更改的金额,3是可用硬币的类型,1 2 3是硬币值列表)输出应该是:0 1 1 2(因为我们有1,2,3作为可用硬币,需要0个硬币更改0,1个硬币更改1,1个硬币更
我目前正在研究leetcode上的硬币兑换动态规划问题--https://leetcode.com/problems/coin-change/. 下面是问题陈述: 我试图实现一种自上而下的记忆方法,在这种方法中,我保留了一个长度数量的数组,其中每个索引表示我可以用来生成该数量的最小硬币数量。 以下是我的Java代码: 我认为这是解决这个问题的正确的动态编程方法,但是我在leetcode上超过了时间