簡體   English   中英

給定數量N消除K個數字以獲得最大可能數量

[英]Given number N eliminate K digits to get maximum possible number

正如標題所說,任務是:

給定數量N消除K數字以獲得最大可能數量。 數字必須保留在其位置。

示例: n = 12345k = 3max = 45 (前三位數消除,數字不得移動到另一位置)。

不知道怎么解決這個問題?
(這不是家庭作業,我正准備進行算法競賽並解決在線評委的問題。)

1 <= N <= 2^60 1 <= K <= 20

編輯:這是我的解決方案。 它的工作:)

#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <cmath>

using namespace std;


int main()
{
    string n;
    int k;

    cin >> n >> k;

    int b = n.size() - k - 1;
    int c = n.size() - b;
    int ind = 0;
    vector<char> res;
    char max = n.at(0);

    for (int i=0; i<n.size() && res.size() < n.size()-k; i++) {
        max = n.at(i);
        ind = i;
        for (int j=i; j<i+c; j++) {
            if (n.at(j) > max) {
                max = n.at(j);
                ind = j;
            }
        }

        b--;
        c = n.size() - 1 - ind - b;
        res.push_back(max);
        i = ind;
    }

for (int i=0; i<res.size(); i++)
    cout << res.at(i);

cout << endl;

    return 0;
}

蠻力應該足夠快,以滿足你的限制: n將有最多19位數。 使用numDigits(n)位生成所有正整數。 如果設置了k位,則刪除與設置位對應的位置的數字。 將結果與全局最優值進行比較,並根據需要進行更新。

復雜性: O(2^log n * log n) 雖然這似乎與O(n)漸近相似,但在實踐中它會更快,因為O(2^log n * log n)中的對數是10對數的基數,這將給出一個小得多的值(1 + log base 10n給你的位數n )。

您可以通過一次生成nn - k組合來避免log n因子,並在生成每個組合時構建由所選n - k位置組成的數字(將其作為參數傳遞)。 這基本上意味着你解決了類似的問題: given n, pick n - k digits in order such that the resulting number is maximum )。

注意:有一種方法可以解決這個問題,但這並不涉及蠻力,但是我也希望向OP展示這個解決方案,因為他在評論中詢問了如何強制執行。 對於最佳方法,研究如果我們從左到右逐位數字構建我們的數字會發生什么,並且對於每個數字d ,我們將刪除所有當前選擇的小於它的數字。 什么時候我們可以刪除它們,何時不能刪除它們?

在最左邊的k + 1個數字中,找到最大的一個(假設它位於第i個位置。如果有多個事件,則選擇最左邊的一個)。 收下。 重復k_new = k-i + 1,newNumber = i + 1的算法到原始數字的n位數。

Eg. k=5 and number = 7454982641
First k+1 digits: 745498
Best number is 9 and it is located at location i=5. 

new_k=1, new number = 82641
First k+1 digits: 82
Best number is 8 and it is located at i=1.

new_k=1, new number = 2641
First k+1 digits: 26
Best number is 6 and it is located at i=2

new_k=0, new number = 41
Answer: 98641

復雜度為O(n),其中n是輸入數字的大小。

編輯:正如iVlad所說,在最壞的情況下,復雜性可以是二次的。 你可以通過保持最大k + 1的堆大小來避免這種情況,這會增加O(nlogk)的復雜性。

以下可能有所幫助

void removeNumb(std::vector<int>& v, int k)
{
    if (k == 0) { return; }
    if (k >= v.size()) {
        v.clear();
        return;
    }
    for (int i = 0; i != v.size() - 1; )
    {
        if (v[i] < v[i + 1]) {
            v.erase(v.begin() + i);
            if (--k == 0) { return; }
            i = std::max(i - 1, 0);
        } else {
            ++i;
        }
    }
    v.resize(v.size() - k);
}

暫無
暫無

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

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