C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++ですべてのタスク完了に必要な最小時間を求めるアルゴリズム

n個の要素を持つ配列Aと、2つの整数kおよびxが与えられているとします。i番目のタスクを完了するには通常A[i]の時間がかかります。配列Aは非降順(昇順)にソートされているものとします。ここで、Amalは最大k個までのタスクを選び、それらを本来のA[i]の代わりにx単位の時間で実行できるものとします(ただし、xは配列内の最小値よりも小さい値です)。このとき、Amalがすべてのタスクを完了するために必要な最小時間を求めるのが目的です。なお、複数のタスクを同時に実行することはできません。

例として、入力が A = [3, 6, 7, 10]、k = 2、x = 2 の場合を考えてみましょう。この場合の出力は 13 になります。最適な戦略は、3番目と4番目のタスクを選び、本来のA[2]とA[3]の代わりにそれぞれx = 2の時間で処理することです。したがって、答えは 3 + 6 + 2 + 2 = 13 となります。

解法のアプローチ

この問題は貪欲法(グリーディ法)で効率的に解くことができます。配列Aがソートされているため、最も時間のかかるタスクから順に短縮対象として選ぶのが最適です。具体的には以下の手順で計算します。

  1. x を k × x に更新します(短縮後の合計時間)。
  2. n を配列Aのサイズとします。
  3. i を 0 から n - k - 1 まで繰り返し処理を行います:
    • t に A[i] を代入します。
    • x に t を加算します。
  4. 最終的な x を結果として返します。

つまり、短縮できない最初の n - k 個のタスクの合計時間に、短縮後の k 個分の時間(k × x)を加えたものが答えになります。

C++による実装例

理解を深めるために、以下の実装例を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
int solve(vector<int> A, int k, int x){
    x = k * x;
    int n = A.size();
    for (int i = 0; i < n - k; i++){
        int t = A[i];
        x += t;
    }
    return x;
}
int main(){
    vector<int> A = { 3, 6, 7, 10 };
    int k = 2;
    int x = 2;
    cout << solve(A, k, x) << endl;
}

入力

{ 3, 6, 7, 10 }, 2, 2

出力

13

計算量について

このアルゴリズムの時間計算量はO(n)です。配列を一度走査するだけで済むため、非常に効率的です。空間計算量もO(1)であり、追加のメモリをほとんど必要としません。ソート済みの配列という前提条件があるため、貪欲に大きい要素から置き換えることで最適解が保証されます。

  1. C++で木の中のすべてのリンゴを収集するための最小時間を求める

    問題概要 n個の頂点からなる無向木を考えます。頂点には0からn-1までの番号が付けられており、いくつかの頂点にはリンゴが置かれています。木の1つの辺を移動するのに1秒かかるとき、頂点0から出発してすべてのリンゴを集め、再び頂点0に戻るまでに必要な最小時間(秒)を求めてください。 無向木の辺は配列 edges として与えられ、edges[i] = [from_i, to_i] は頂点 from_i と頂点 to_i を結ぶ辺が存在することを表します。さらに、hasApple というブール値の配列も与えられ、hasApple[i] = true の場合は頂点 i にリンゴが存在し、false の

  2. C++で全従業員に緊急ニュースを伝えるのに必要な時間を求める方法(BFS活用)

    問題の概要ある会社にはn人の従業員が在籍しており、各従業員には0からn-1までの一意なIDが割り振られています。会社のトップ(社長)はheadIDで表されます。各従業員には必ず一人の直属の上司が存在し、それはmanager配列によって与えられます。manager[i]はi番目の従業員の直属の上司を意味し、社長の場合はmanager[headID] = -1となります。なお、組織の上下関係は木構造になっていることが保証されています。社長は緊急のニュースを全従業員に伝えたいと考えています。まず社長が直属の部下に連絡し、その部下たちがさらに自分の部下へと伝えていくことで、ニュースは組織全体へと広まっ