我的任务是创建一个函数,该函数接收硬币的数组/向量和要达到的值。该函数不是简单地返回所需的最小硬币数量,而是必须返回一个数组/向量,该数组/向量基本上具有每种面额应使用多少硬币的信息,以便使用最少量的硬币。
例如,数组coins
保持[1, 2, 5, 10]
,所需的值为12美分。该函数应该接受所有这些并返回一个包含以下数字的数组:[0, 1, 0, 1]
,表示应使用0
1美分硬币,1
2美分应使用硬币,0
应使用5美分硬币,并且应使用1
10美分硬币。
我正在使用c ++并且必须使用动态编程算法,我能够做到只返回所需的最小硬币数量。但是,我不确定如何生成正确的数字来填充要返回的数组或向量。
这就是我目前所拥有的:
int *minCoins(int coins[], int size, int value)
{
int *table = new int[value + 1];
table[0] = 0;
for (int i = 1; i <= value; i++)
table[i] = INT_MAX;
for (int i = 1; i <= value; i++)
{
for (int j = 0; j < size; j++)
if (coins[j] <= i)
{
int sub_res = table[i - coins[j]];
if (sub_res != INT_MAX && sub_res + 1 < table[i])
table[i] = sub_res + 1;
}
}
//this is where I am unsure of what to do. should I return table or modify coins somehow?
}
感谢任何帮助!
答案 0 :(得分:1)
我们可以另外存储用于获取apply
的最后一个硬币类型table[i]
而不是仅存储背包中i
的最小硬币数last[i]
table[i]
1}}。之后,我们可以在循环中i -= coins[last[i]]
获取所有硬币,直到i
变为零。
在代码中:
int *minCoins(int coins[], int size, int value)
{
int *last = new int[value + 1]; // this line added
int *table = new int[value + 1];
table[0] = 0;
for (int i = 1; i <= value; i++)
table[i] = INT_MAX;
for (int i = 1; i <= value; i++)
{
for (int j = 0; j < size; j++)
if (coins[j] <= i)
{
int sub_res = table[i - coins[j]];
if (sub_res != INT_MAX && sub_res + 1 < table[i])
{
table[i] = sub_res + 1;
last[i] = j; // this line added
}
}
}
int *res = new int[size]; // this will be the answer
for (int i = 0; i < size; i++)
res[i] = 0;
int cur = value; // the value left
while (cur > 0)
{
res[last[cur]] += 1; // add the current coin
cur -= coins[last[cur]]; // proceed to the next coin
}
delete[] table;
delete[] last;
return res;
}
答案 1 :(得分:0)
你可以使用pair&lt; int,bool&gt; dp [i] [j]其中i是1到i的答案,其值为j,那么如果我们使用第i个硬币然后dp [i] [j] .second = true则为false然后在到达时结束您可以使用递归函数的最小答案,并且对于您到达的每个dp [i] [j],如果bool为真,则必须转到dp [i - 1] [j - a [i]]并添加i来回答(a是硬币的价值)否则你必须在没有做任何事情的情况下去dp [i - 1] [j]
dp update:
if(dp[i - 1][j].first < dp[i - 1][j - a[i]].first + 1)
{
dp[i][j].second = false;
dp[i][j].first = dp[i - 1][j].first;
}
else
{
dp[i][j].second = true;
dp[i][j].first = dp[i - 1][j - a[i]].first + 1;
}
递归函数:
void func(int i,int j)
{
if(i == -1)
return;
if(dp[i][j].second)
ans.push_back(i), func(i - 1,j - a[i]);
else
func(i - 1,j);
}