【问题标题】:Given N coins, each coin can be used at most T times. Is it possible to make value W using minimum N coins?给定 N 个硬币,每个硬币最多可以使用 T 次。是否可以使用最少的 N 个硬币来产生 W 值?
【发布时间】:2020-08-15 19:39:31
【问题描述】:

输入格式:

N T(N = 硬币数量,T = 次数)
C1, C2 .... CN

从我的解决方案中,我得到了这个......

输入:
2 4
5 8
37

输出:
5(这是有效的,因为 37 = (8*4)+(5*1))

输入:
2 2
5 10
30

输出:
3(这里的输出应该是4,因为我不能使用硬币超过2次)。

我的解决方案中的错误在哪里?

#include<bits/stdc++.h>
using namespace std;
int coins[100], N, T, mem[100][100];
int solve(int p, int w, int us[])
{
    if(p==N || w<=0){
        if(w==0) return 0;
        return 1e5;
    }
    if(mem[w][p]!=-1) return mem[w][p];
    int ans=1e5;

    if(us[p]<T){
        us[p]++;
        ans=min(1+solve(p, w-coins[p], us), ans);
        us[p]--;
    }
    ans=min(ans, solve(p+1, w, us));
    return mem[w][p]=ans;
}
int main()
{
    cin>>N>>T;
    for(int i=0;i<N;i++){
        cin>>coins[i];
    }
    int w, us[100];
    cin>>w;
    memset(mem, -1, sizeof (mem));
    memset(us, 0, sizeof (us));
    cout<<solve(0, w, us)<<endl;
    return 0;
}

【问题讨论】:

  • 是 w 100 的最大值吗?
  • 是的,我只是使用 100 表大小进行测试,如果我的第二个输入显示正确的结果就可以了。谢谢@GolamMazidSajib
  • T 的最大值?
  • T 的最大值 = 50
  • 输出的定义是什么?就像问题似乎是/否,但答案是 3/5 这些数字是多少?

标签: c algorithm dynamic-programming coin-change


【解决方案1】:

代码问题:

你检查if(us[p]&lt;T),但是当你调用函数时你减去w-coins[p]...

根据你的逻辑这个块:

if(us[p]<T){
        us[p]++;
        ans=min(1+solve(p, w-coins[p], us), ans);
        us[p]--;
    }

应该是:

if(us[coins[p]]<T){
        us[coins[p]]++;
        ans=min(1+solve(p, w-coins[p], us), ans);
        us[coins[p]]--;
    }

您的解决问题:

您的记忆将不起作用,因为您在函数中传递了p,w and us[],但您只记住了p and w.. 当您记住所有相同值p and w 和不同值us[].. 您的解决方案将不起作用..

解决办法:

你需要用硬币数组T次取新数组...

让我们投币:5, 10.. 和 t = 2

那么新的数组硬币数组将是:5 5 10 10

现在,如果您想创建 30,然后尝试使用新数组创建 30

试试这个代码:

#include <bits/stdc++.h>

using namespace std;
int coins[5005], N, M, T, mem[105][5005];
int solve(int p, int w)
{
    if(p==N || w<=0){
        if(w==0) return 0;
        return 1e5;
    }
    if(mem[w][p]!=-1)
        return mem[w][p];
    return mem[w][p] = min(solve(p+1,w), 1 + solve(p+1, w-coins[p]));
}
int main()
{
    cin>>N>>T;
    M = 0;
    for(int i=0;i<N;i++){
        int a;
        cin>>a;
        for (int j = 0; j < T; j++) {
            coins[M++] = a;
        }
    }
    N = M;
    int w, us[100];
    cin>>w;
    memset(mem, -1, sizeof (mem));
    cout<<solve(0, w)<<endl;
    return 0;
}

【讨论】:

  • 尝试您的解决方案后,第二个测试用例的输出仍然是 3!我需要一个解决方案。您可以修改我的代码以获得正确的判断。谢谢
  • @MinhajulIslam 我没有给出解决方案......检测代码中的错误也给出了你的逻辑错误......我只能在回答中给出提示。你需要尝试
  • 知道了!您只需实现最小数量的硬币即可获得 W 值,其中硬币最多可以使用一次。硬币数组最多有 T 次所有硬币。不错....顺便说一句,我还使用递归函数中的循环解决了它。谢谢@GolamMazidSajib
猜你喜欢
  • 2016-04-25
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 2017-06-21
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多