簡體   English   中英

在這種情況下,為什么貪婪的方法不起作用?

[英]Why doesn't greedy approach work in this case?

我正在嘗試解決以下SPOJ問題

輸入是: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;
}

一個簡單的計數器示例將是兩種類型的硬幣(weight,value) = {(2,3), (3,3)} ,帶有重量為4的小豬。您將嘗試將“更差”的硬幣放入重量3,將無法匹配四個重量。 但是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(Weight,#coins_in_currency)調用f(Weight,#coins_in_currency)

當使用DP(自下而上或自上而下)時,該解決方案的時間復雜度為O(n*W) ,其中W是小豬的期望權重, n是貨幣中的硬幣數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM