最大の製品
タイトル説明
正の整数は、一般に、いくつかの互いに異なる自然数に分割すること(3 = 1 + 2 \)\ \ (1 + 3 = 4 \)、\ (1 + 4 = 5 = 3 + 2 \ )、\ (1 + 5 = 6 = 2 + 4 \) 。
今すぐあなたのタスクは、正の整数で割り当てることです\(nは\) 、いくつかの異なる自然数とし、これらの数値の最大の天然物に。
入出力フォーマット
入力形式
唯一の正の整数\(N- \) 、(\ (3 \ n型のLeq \のLeq 10000 \) )。
出力フォーマット
最初の行は、と昇順にに隣接するスペースで区切られた、プログラムの数との間に分解されます。2行目は最大の製品です。
サンプル入力と出力
入力サンプル#1
10
サンプル出力#1
2 3 5
30
分析
この問題の鍵は、大規模なプロットとほぼ原則とをつかむことです。
そして、近くに大規模なプロットを持つ2つの数字と特定の、小さな差が、JIDA。
すなわち、想定される\(A \ B GEを\) 、次いで\((A + 1)\タイムズ(B - 1)<A \タイムズB \) 。
:単純な証明( - 1)= A \タイムズB + B - A - (A + 1)\タイムズ(B 1 \)\、およびので\(A \ GEのB \) 、そう\(B - \ル0 \) 。最後に、この式マイナスがあるので、( - <A \タイムズB \ 1)(A + 1)\タイムズ(B。)\。
私たちは、ほぼ2の拡大や原則を持つ大規模なプロットを考えてみましょう。この質問は、互いに異なるすべての数字は、我々が要因な限りしたいことが必要であるため、それらはより近く、より良い持っています。だから、私たちは2で始まる自然数の数を列を構築し、その後まとめ、これはより大きくなるまですることができます\(N- \) 。
なぜ\(2 \)を開始?場合は\(1 \)開始し、その後、\(1 \) 、この番号と作品が、その後の製品を用いないで全体を無駄にしました。失血!
しかし、この時点で、かつより大きく、(N- \)\、そして仮定は、余分なことである(K \)は\その後、ケースが置かれ、バー(K \)\アイテム外に移動していること。この時点では、列の正しい数を取得することです-
これ?
- いいえ、あなたは考えるのを忘れて\(K = 1 \)の状況を。この場合の最適解は、その項目の最後に1を追加し、2の開始時に除去されます。
- あなたも考慮するのを忘れて\(N = 3,4 \)ケースを、この時点でのソリューションです\(N \)そのもの。
実際に、私は上記の溶液は、厳格な思考Iの打ち上げに基づいていない、私は良いプログラムの厳格な証明を考えていないという問題があり、小型のパートナーは私に言うことができますか?私は感謝しています。
そうそう、ああこの質問はまた、高精度を必要とし、忘れてはいけません(N- \ル10000 \)\、高精度の父親はそれを参照してください開かないでください。
コード
このコードは、高精度のテンプレートを使用しています。リンク
/*
* @Author: crab-in-the-northeast
* @Date: 2020-04-02 00:58:54
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2020-04-02 01:10:27
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cassert>
#include <vector>
int max(int a,int b) {
return a > b ? a : b;
}
struct ubigint {
typedef unsigned long long ull;
static const int base = 100000000;
static const int width = 8;
std :: vector<int> s;
ubigint& clear_zero() {
while(!s.back() && s.size() > 1) s.pop_back();
return *this;
}
ubigint(ull num = 0) {*this = num;}
ubigint(std :: string str) {*this = str;}
ubigint& operator = (ull num) {
s.clear();
do {
s.push_back(num % base);
num /= base;
}while(num);
return *this;
}
ubigint& operator = (const std :: string& str) {
s.clear();
int x;
int len = (str.length() - 1) / width + 1;
for(int i = 0; i < len; i++) {
int endidx = str.length() - i * width;
int startidx = max(0, endidx - width);
int x;
sscanf(str.substr(startidx, endidx - startidx).c_str(), "%d", &x);
s.push_back(x);
}
return (*this).clear_zero();
}
bool operator < (const ubigint& b) const {
if(s.size() != b.s.size()) return s.size() < b.s.size();
for(int i = s.size() - 1; i >= 0; i--)
if(s[i] != b.s[i])
return s[i] < b.s[i];
return false;
}
bool operator > (const ubigint& b) const {return b < *this; }
bool operator <= (const ubigint& b) const {return !(b < *this);}
bool operator >= (const ubigint& b) const {return !(*this < b);}
bool operator == (const ubigint& b) const {return !(b < *this) && !(b > *this);}
bool operator != (const ubigint& b) const {return b < *this || *this < b;}
ubigint operator + (const ubigint& b) const {
ubigint res;
res.s.clear();
for(int i = 0, x = 0; x || i < s.size() || i < b.s.size(); i++, x /= base) {
if(i < s.size()) x += s[i];
if(i < b.s.size()) x += b.s[i];
res.s.push_back(x % base);
}
return res.clear_zero();
}
ubigint operator - (const ubigint& b) const {
assert(*this >= b);
ubigint res;
res.s.clear();
for(int i = 0, last = 0;last || i < s.size() || i < b.s.size();i++) {
int x = s[i] + last;
if(i < b.s.size()) x -= b.s[i];
if(x < 0) {
last = -1;
x += base;
}else last = 0;
res.s.push_back(x);
}
return res.clear_zero();
}
ubigint operator * (const ubigint& b) const {
std :: vector<ull> tmp(s.size() + b.s.size(),0);
ubigint res;
res.s.clear();
for(int i = 0; i < s.size(); i++)
for(int j = 0; j < b.s.size(); j++)
tmp[i + j] += ull(s[i]) * b.s[j];
ull last = 0;
for(int i = 0; last || i < tmp.size(); i++) {
ull x = tmp[i] + last;
res.s.push_back(x % base);
last = x / base;
}
return res.clear_zero();
}
int midsearch(const ubigint& b, const ubigint& m) const {
int l = 0, r = base - 1;
while(1) {
int mid = l + r >> 1;
if(b * mid <= m && b * (mid + 1) > m) return mid;
if(b * mid <= m) l = mid;
else r = mid;
}
}
ubigint operator / (const ubigint& b) const {
assert(b > 0);
ubigint res = *this, mod;
for(int i = s.size() - 1; i >= 0; i--) {
mod = mod * base + s[i];
res.s[i] = midsearch(b, mod);
mod -= b * res.s[i];
}
return res.clear_zero();
}
ubigint operator % (const ubigint& b) const {
assert(b > 0);
ubigint res = *this, mod;
for(int i = s.size() - 1; i >= 0; i--) {
mod = mod * base + s[i];
res.s[i] = midsearch(b, mod);
mod -= b * res.s[i];
}
return mod.clear_zero();
}
ubigint& operator += (const ubigint& b) {*this = *this + b; return *this;}
ubigint& operator -= (const ubigint& b) {*this = *this - b; return *this;}
ubigint& operator *= (const ubigint& b) {*this = *this * b; return *this;}
ubigint& operator /= (const ubigint& b) {*this = *this / b; return *this;}
ubigint& operator %= (const ubigint& b) {*this = *this % b; return *this;}
friend std :: istream& operator >> (std :: istream& in, ubigint& x) {
std :: string str;
if(!(in >> str)) return in;
x = str;
return in;
}
friend std :: ostream& operator << (std :: ostream& out, ubigint x) {
out << x.s.back();
for(int i = x.s.size() - 2; i >= 0; i--) {
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for(int j = 0; j < strlen(buf); j++)
out << buf[j];
}
return out;
}
};
int main() {
int n;
std :: cin >> n;
int sum = 0, to;
if(n <= 4) {
std :: cout << n << std :: endl << n << std :: endl;
return 0;
}
for(int i = 2; sum <= n; i++) {
sum += i;
to = i;
}
ubigint ans = 1;
for(int i = 2; i <= to; i++) {
if(sum - n == 1) {
if(i == 2) continue;
if(i == to) {
std :: cout << i + 1 << ' ';
ans *= (i + 1);
break;
}
}
if(i != sum - n) {
std :: cout << i << ' ';
ans *= i;
}
}
std :: cout << std :: endl << ans << std :: endl;
return 0;
}