C++で2つの配列からX個とY個の要素を選び、合計を最大化する方法
サイズNの2つの配列が与えられたとき、1つ目の配列からX個、2つ目の配列からY個の要素を選択して、その合計を最大化することが課題です。
具体的な例を使って、何をすべきか見ていきましょう。
入力例1
arr1 = {1,2,3,4,5} ; X=2
arr2 = {1,3,5,2,7}; Y=3出力例1
最大合計値 : 24
解説: arr1から2つ、arr2から3つの数値を選びます。arr1の大きい方から2つは「4, 5」、arr2の大きい方から3つは「3, 5, 7」です。これら5つの要素の合計は24となり、これが条件を満たす最大値になります。
入力例2
arr1 = {10,13,16,14}; X=1
arr2 = {4,1,2,1}; Y=2出力例2
最大合計値 : 22
解説: arr1から1つ、arr2から2つの数値を選びます。arr1の最大値は「16」、arr2の大きい方から2つは「4, 2」です。これら3つの要素の合計は22となり、これが最大値となります。
プログラムで使用するアプローチ
入力として配列arr1[]とarr2[]、およびXとYの値を受け取ります。
両方の配列を昇順にソートします。
ソート後は末尾の要素が最も大きくなるため、arr1からは末尾のX個、arr2からは末尾のY個を取り出します。
手順3で選んだ要素の合計を返します。それが最大の合計値となるためです。
注意:sort(arr[], int)はソート済みの配列を返すものと仮定しています。
実装例
#include <iostream>
using namespace std;
int max_sum(int arr1[],int arr2[], int length,int X,int Y){
// 配列をソートする
sort(arr1,length);
sort(arr2,length);
int sum=0;
int i;
// arr1の末尾X個とarr2の末尾Y個を加算する
for(i=0;i<X;i++){
sum+=arr1[length-i-1];
}
for(i=0;i<Y;i++){
sum+=arr2[length-i-1];
}
return(sum);
}
// ドライバープログラム
int main(){
int arr1[]={1,1,1,3,7};
int arr2[]={1,1,2,3,5};
int x=3,y=2;
printf( "1番目と2番目の配列からX個とY個の要素を選んだ場合の最大化された合計は %d",max_sum(arr1,arr2,5,x,y));
return 0;
}出力結果
上記のコードを実行すると、次の出力が得られます。
1番目と2番目の配列からX個とY個の要素を選んだ場合の最大化された合計は 19
このアルゴリズムの計算量は、ソートにO(N log N)、要素の選択と合計にO(X + Y)かかるため、全体としてO(N log N)となります。貪欲法(グリーディ法)に基づくシンプルな手法で、各配列から最大の要素を優先的に選ぶことで確実に最大の合計を得られます。
-
C++で配列内の最小値と2番目に小さい値を検索する方法
n個の要素からなる配列が与えられたとき、その中で最も小さい要素(最小値)と、2番目に小さい要素を見つける必要があります。ここでいう「2番目に小さい要素」とは、最小値より大きい値の中で最小のものを指します。この問題は、配列の各要素を先頭から順に走査しながら、現時点での最小値と2番目に小さい値を適切に更新していくことで解決できます。アルゴリズムの考え方まず、最小値(first)と2番目に小さい値(sec)を、それぞれ int 型の最大値 INT_MAX で初期化します。次に配列を一巡するループの中で、以下の条件に従って値を更新していきます。現在の要素が最小値より小さい場合:2番目に小さい値を元の最
-
C++で配列の全要素にXOR演算を適用して合計を最小化する方法
問題の説明サイズNの配列が与えられます。配列の各要素とある整数XとのXOR演算を行ったとき、その結果の合計が最小となるようなXを見つけてください。例として、入力配列が arr[] = {8, 5, 7, 6, 9} の場合、最小合計は 30 になります。各配列要素の2進数表現は次のとおりです。8 : 1000 5 : 0101 7 : 0111 6 : 0110 9 : 1001X = 5 のとき、XOR演算後の各値と合計は以下のようになります。8 ^ 5 = 13 5 ^ 5 = 0 7 ^ 5 = 2 6 ^ 5 = 3 9 ^ 5 = 12 合計 = 30(13 + 0 + 2 + 3