Cod sursa(job #1757187)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 14 septembrie 2016 17:36:35
Problema NumMst Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#ifndef INFOARENA
#include <fstream>
#else
#include <bits/stdc++.h>
#endif
using namespace std;

constexpr int kMaxSqrt = 3200;
constexpr int kMaxPrimes = 453;

double dp[kMaxPrimes][kMaxSqrt];
int from[kMaxPrimes][kMaxSqrt];
bool mark[kMaxSqrt];
int primes[kMaxPrimes];

int main() {
	ifstream cin("nummst.in");
	ofstream cout("nummst.out");
	
	int N; cin >> N;
	
	int lowest_divisor = 2;
	while (N / lowest_divisor * lowest_divisor != N) {
		lowest_divisor += 1 + (lowest_divisor != 2);
	}

	if (lowest_divisor < 5) {
		cout << N / lowest_divisor << ' ' << N - N / lowest_divisor << '\n';
		return 0;
	}

	int num_primes = 1;
	primes[0] = 2;
	for (int i = 3; i <= lowest_divisor; i += 2) {
		if (!mark[i]) {
			primes[num_primes++] = i;
			for (int j = 3 * i; j <= lowest_divisor; j += 2 * i) {
				mark[j] = true;
			}
		}
	}

	for (int i = 1; i <= num_primes; i += 1) {
		const int prime = primes[i - 1];
		const double prime_logarithm = log(prime);
		for (int j = 0; j <= lowest_divisor; j += 1) {
			for (int step = 1, k = prime; k <= lowest_divisor - j; k *= prime, step += 1) {
				const double option = dp[i - 1][j] + prime_logarithm * step;
				if (option > dp[i][j + k]) {
					dp[i][j + k] = option;
					from[i][j + k] = k;
				}
			}
		}
		for (int j = 0; j <= lowest_divisor; j += 1) {
			if (dp[i][j] < dp[i - 1][j]) {
				dp[i][j] = dp[i - 1][j];
				from[i][j] = 0;
			}
		}
	}

	int state = lowest_divisor;
	for (int i = num_primes; i >= 1; i -= 1) {
		if (from[i][state] != 0) {
			cout << N / lowest_divisor * from[i][state] << ' ';
			state -= from[i][state];
		}
	}
	cout << '\n';

	return 0;
}