Cod sursa(job #585775)

Utilizator freak93Adrian Budau freak93 Data 30 aprilie 2011 11:47:50
Problema NumMst Scor 50
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 1.56 kb
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const char iname[] = "nummst.in";
const char oname[] = "nummst.out";
const int maxn = 3000;

ifstream f(iname);
ofstream g(oname);

int prim[maxn], prime[maxn];
double val[maxn], dp[2][maxn];
short from[500][maxn];

int main() {
	int N, k;
	f >> N;
	int i;
	for (i = 2; N % i; ++i);
	if (N % i)
		i = N;
	k = N / i;
	N /= k;
    if (N == 2) {
		g << k << " " << k << " ";
		g << "\n";
		return 0;
	}
	fprintf(stderr, "%d\n", N);

	//erathostene
	int p = 0;
	val[p] = 0;
	for (i = 2; i <= N; ++i)
		if (prim[i] == 0) {
			for (int j = i * i; j <= N; j += i)
				prim[j] = 1;
        	prime[++p] = i;
			val[p] = log(i);
		}
	//fprintf(stderr, "%d -> %d\n", prim[757], prim[1321]);
    //fprintf(stderr, "%d\n", p);
	dp[0][0] = 0;
	for (i = 1; i <= p; ++i) {
		memset(dp[i & 1], 0, sizeof(dp[0]));
		for (int j = 0; j <= N; ++j) {
			int p = prime[i];
			int pas = 0;
			while (j + p <= N) {
				++pas; 
				double aux = dp[i - 1 & 1][j] + val[prime[i]] * pas;
				if (aux > dp[i & 1][j + p])
					dp[i & 1][j + p] = aux, from[i][j + p] = p;
				p *= prime[i];
			}
			if (dp[i - 1 & 1][j] > dp[i & 1][j])
				dp[i & 1][j] = dp[i - 1 & 1][j], from[i][j] = 0;
		}
	}

    vector<int> answer;
	int j = N;
	for (i = p; i >= 0; j -= from[i][j], --i)
		if (from[i][j] > 0)
			answer.push_back(from[i][j]);
	if (j > 0)
		answer.push_back(j);
	sort(answer.begin(), answer.end());
	for (vector<int>::iterator it = answer.begin(); it != answer.end(); ++it)
		g << *it * k << " ";
	g << "\n";
}