[プログラマー/CPP/JS]ベストコレクション
9509 ワード
[程序]最适合的集合
1.質問
n個の自然数からなる繰り返し集合(複数の集合、都合のよい後に総称して「集合」と呼ぶ)では、以下の2つの条件を満たす集合を最適集合と呼ぶ.
各要素の和はSの数の集合である.
上記の条件を満たす各要素の積の最大の集合.
たとえば、2つの自然数の合計が9の4つのセットがあります.
{ 1, 8 }, { 2, 7 }, { 3, 6 }, { 4, 5 }
各要素の最大積{4,5}が最適な集合である.
セット内の要素の個数nとすべての要素の和sをパラメータとして指定した場合、最適なセットを返す解関数を完了します.
2.制限
最良のセットは、昇順に並べられた1次元配列(list,vector)を返します.
最適なセットが存在しない場合は、1次元配列(list,vector)に-1を入力して返します.
自然数の個数nは、1以上10000以下の自然数である.
すべての要素の合計は、1または10または1000000以下の自然数です.
3.解答
적절한 알고리즘이나 설명이 생각나지 않는다.
다 쓰고 보니 DP인 것 같기도..?
값들이 균등할 수록 곱의 최댓값이 커진다.
문제를 작게 쪼갤 수 있다.
현재 가장 균등한 값
= s/n
s
減算s/n
、n
減算1.問題を
s - s/n
の和を持つn-1
個数の最大積に変換する.n
二.n
2は2に等しく、2つに割って、そのまま並べることができます.n
2であれば優先順位にn/2
の値を挿入します.n
が偶数の場合はn/2
を挿入します.n
奇数であれば挿入n/2+1
더 해서 8이 되는 두 수 중 곱이 가장 큰 수는 (4, 4)
더 해서 9가 되는 두 수 중 곱이 가장 큰 수는 (4, 5)
4.最初のコードと異なる点
답이 안 나왔다.
사실 난 천재가 아닐까?
5.コード
#include <string>
#include <vector>
using namespace std;
vector<int> solution(int n, int s) {
vector<int> answer;
if(s < n) {
answer.push_back(-1);
return answer;
}
while(n > 2) {
int result = s / n;
answer.push_back(result);
s -= result;
n--;
}
answer.push_back(s/2);
if(s%2==0){
answer.push_back(s/2);
}
else{
answer.push_back(s/2+1);
}
return answer;
}
6.コード(JS)
function solution(n, s) {
const answer = [];
while (n > 2) {
const small = Math.floor(s / n);
if (small === 0) return [-1];
answer.push(small);
s -= small;
n -= 1;
}
answer.push(Math.floor(s / 2), Math.ceil(s / 2));
return answer;
}
7.コード(失敗/JS)
function solution(n, s) {
if (s < n) return [-1];
const dfs = (len, target, res) => {
if (len === 2) return [Math.floor(target / 2), Math.ceil(target / 2)];
return [...res, Math.floor(target / len), ...dfs(len - 1, Math.ceil((target / len) * (len - 1)), res)];
};
return dfs(n, s, []);
}
top-downで簡潔なコードを書こうとしたが、効率の問題でパスできなかった.Reference
この問題について([プログラマー/CPP/JS]ベストコレクション), 我々は、より多くの情報をここで見つけました https://velog.io/@e7838752/programmers-bestSetテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol