Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么';贪婪的方法在这种情况下不起作用吗?_C++_Algorithm_Greedy - Fatal编程技术网

C++ 为什么';贪婪的方法在这种情况下不起作用吗?

C++ 为什么';贪婪的方法在这种情况下不起作用吗?,c++,algorithm,greedy,C++,Algorithm,Greedy,我试图解决以下问题 输入为: 1.硬币中一定数量货币的总重量, 2.旧货币硬币的价值和相应重量 目标是找到给定金额货币的最低可能货币价值 我的方法是按照各自的价值/重量比按升序对货币的硬币进行排序,然后贪婪地将第一枚硬币的重量尽可能多地拟合到总重量中(跟踪拟合的次数),然后将第二枚硬币的重量尽可能多地拟合到剩余的硬币中,等等。,对于所有的硬币,或者直到余数为零(如果不是,则情况不可能) 法官说我的回答是错误的。你能给我一个关于算法错误的提示吗 我的代码在这里: #include <iost

我试图解决以下问题

输入为: 1.硬币中一定数量货币的总重量, 2.旧货币硬币的价值和相应重量

目标是找到给定金额货币的最低可能货币价值

我的方法是按照各自的价值/重量比按升序对货币的硬币进行排序,然后贪婪地将第一枚硬币的重量尽可能多地拟合到总重量中(跟踪拟合的次数),然后将第二枚硬币的重量尽可能多地拟合到剩余的硬币中,等等。,对于所有的硬币,或者直到余数为零(如果不是,则情况不可能)

法官说我的回答是错误的。你能给我一个关于算法错误的提示吗

我的代码在这里:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef unsigned int weight_t;
typedef unsigned int value_t;

struct coin {
    weight_t weight;
    value_t value;
    double value_per_gram;
};

coin make_coin(weight_t weight, value_t value) {
    coin ret;
    ret.weight = weight;
    ret.value = value;
    ret.value_per_gram = (double)(value/weight);
    return ret;
}

bool compare_by_value_per_gram(const coin& coin1, const coin& coin2) {
    return coin1.value_per_gram < coin2.value_per_gram;
}

int main() {
    unsigned int test_cases;
    cin >> test_cases;
    while(test_cases--) {
        unsigned int number_of_coins = 0;
        weight_t empty_pig, full_pig, coins_weight, coin_weight, min_value = 0;
        value_t coin_value = 0;
        vector<coin> coins;
        vector<unsigned int> how_many_coins;
        cin >> empty_pig >> full_pig;
        coins_weight = full_pig - empty_pig;
        cin >> number_of_coins;

        while(number_of_coins--) {
            cin >> coin_value >> coin_weight;
            coins.push_back(make_coin(coin_weight, coin_value));
        }
        sort(coins.begin(), coins.end(), compare_by_value_per_gram);

        how_many_coins.resize(coins.size());
        for(unsigned int i = 0; i < coins.size() && coins_weight > 0; i++) {
            how_many_coins[i] = coins_weight/coins[i].weight;
            coins_weight %= coins[i].weight;
            min_value += coins[i].value * how_many_coins[i];
        }
        if(coins_weight == 0) cout << "The minimum amount of money in the piggy-bank is " << min_value << "." << endl;
        else cout << "This is impossible." << endl;
    }
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
typedef无符号整数权重;
typedef无符号整数值\u t;
结构币{
重量;
价值(t)价值;;
每克双值;
};
硬币制造硬币(重量、价值){
投币网;
ret.weight=重量;
ret.value=值;
每克回收价值=(双倍)(价值/重量);
返回ret;
}
按每克价值进行布尔比较(常量硬币和硬币1,常量硬币和硬币2){
返回coin1.value\u per\u gram>测试案例;
而(测试用例--){
硬币的无符号整数=0;
重量-空清管器、满清管器、硬币重量、硬币重量、最小值=0;
价值=硬币价值=0;
矢量硬币;
矢量多少枚硬币;
cin>>空清管器>>满清管器;
硬币重量=满猪-空猪;
cin>>硬币的数量;
while(硬币的数量--){
cin>>硬币价值>>硬币重量;
硬币。推回(制造硬币(硬币重量,硬币价值));
}
排序(coins.begin()、coins.end()、按每克值比较);
多少个硬币。调整大小(coins.size());
对于(无符号整数i=0;i0;i++){
多少枚硬币[i]=硬币重量/硬币[i]。重量;
硬币重量%=硬币[i]。重量;
最小值+=硬币[i]。值*多少枚硬币[i];
}

如果(coins_weight==0)不能一个简单的反例将是两种类型的硬币
(weight,value)={(2,3),(3,3)},小猪的重量为4。你将尝试放置“更差”的硬币,重量为3,无法与4的重量相匹配。但2*(2,3)硬币的情况非常可能

通过对解决方案进行一些修改,可以非常类似地解决此问题:

这个想法是模仿穷举搜索。在每一步中,你看着当前的候选硬币,你有两个选择:接受它,或者前进到下一个硬币

f(x,i) = INFINITY          x < 0 //too much weight 
f(0,i) = 0                       //valid stop clause, filled the piggy completely.
f(x,0) = INFINITY          x > 0 //did not fill the piggy
f(x,i) = min{ f(x,i-1) , f(x-weight[i], i) + value[i] } //take minimal guaranteed value
               ^                  ^
        coin is not used      use this coin
            anymore
f(x,i)=无穷大x<0//权重过大
f(0,i)=0//有效的停止子句,完全填满了小猪。
f(x,0)=无穷大x>0//未填充小猪
f(x,i)=最小{f(x,i-1),f(x-weight[i],i)+值[i]}//取最小保证值
^                  ^
这枚硬币不用
不再
使用
f(重量,#货币中的#硬币)


使用DP(自下而上或自上而下)时,此解决方案的时间复杂度为
O(n*W)
其中,
W
是小猪的期望重量,
n
是货币中的硬币数量。

考虑:如果你有美元、30美分、25美分、10美分、5美分和1美分的硬币,贪婪的最少硬币数量算法将不起作用。简单的情况是,你有2和5美分的硬币(重量相同)你需要支付6。这里唯一的解决方案是3乘以2,但你会先找到5,然后再找不到正确的答案?我认为你应该使用DP而不是贪婪。银行里有3克硬币,1分2克硬币和2分3克硬币。@mirgee你读过关于动态编程的书吗?你应该在任何好的算法中找到关于它的章节thms手册(如Skiena)。这种穷举搜索方法不起作用,因为对于某些输入,它最终会比较两个无穷大。但是,从您的wikipedia链接中找到的无界背包问题的动态规划解决方案是可行的。这是我尝试的解决方案。@mirgee此解决方案是背包的一个微小变化。主要的不同是背包允许有组合重量小于容量的项目,此问题不存在。如果不适用于您,则公式中有一点不准确,但一般方法是正确的,或者代码中有错误。