Pagini recente » Cod sursa (job #882247) | Cod sursa (job #30966) | Cod sursa (job #1936762) | Cod sursa (job #1692972) | Cod sursa (job #1757200)
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
ifstream cin("nummst.in");
ofstream cout("nummst.out");
cin.tie(0);
ios_base::sync_with_stdio(0);
int N; cin >> N;
int lowestDivisor = 2;
while(N != N / lowestDivisor * lowestDivisor) {
lowestDivisor = (lowestDivisor + 2 - (lowestDivisor == 2));
}
// gcd = N / lowestDivisor
// scriu lowestDivisor ca suma de numere prime intre ele ale caror produs sa fie maximal
if(lowestDivisor < 5) {
cout << N / lowestDivisor << ' ' << N - N / lowestDivisor << '\n';
return 0;
}
vector<int> primes;
vector<bool> mark(lowestDivisor + 1, false);
for(int i = 2; i <= lowestDivisor; ++i) {
if(!mark[i]) {
primes.push_back(i);
for(int j = i * i; j <= lowestDivisor; j += i)
mark[j] = true;
}
}
vector<double> dp[2];
dp[0].resize(lowestDivisor + 1);
fill(dp[0].begin(), dp[0].end(), .0);
dp[1].resize(lowestDivisor + 1);
vector<vector<int>> from(primes.size() + 1, vector<int>(lowestDivisor + 1, 0));
for(int ptr = 1, i = 1; i <= (int)primes.size(); ++i, ptr ^= 1) {
const double lgPrime = log(primes[i - 1]);
fill(dp[ptr].begin(), dp[ptr].end(), .0);
for(int j = 0; j + primes[i - 1] <= lowestDivisor; ++j) {
for(int step = 1, k = primes[i - 1]; j + k <= lowestDivisor; k *= primes[i - 1], step++) {
if(dp[ptr][k + j] < dp[ptr ^ 1][j] + lgPrime * step) {
dp[ptr][k + j] = dp[ptr ^ 1][j] + lgPrime * step;
from[i][k + j] = k;
}
}
}
for(int j = 0; j <= lowestDivisor; ++j) {
if(dp[ptr][j] < dp[ptr ^ 1][j]) {
dp[ptr][j] = dp[ptr ^ 1][j];
from[i][j] = 0;
}
}
}
int state = lowestDivisor;
for(int i = (int)primes.size(); i >= 1; --i) {
if(from[i][state] != 0) {
cout << from[i][state] * N / lowestDivisor << ' ';
state -= from[i][state];
}
}
cout << '\n';
return 0;
}