Cod sursa(job #2247022)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 27 septembrie 2018 19:40:08
Problema NumMst Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>

using namespace std;

const float INF = 1e3;
const int SQRT = 3500;

int low[SQRT + 1];

vector < vector <double> > dp;
vector < vector <short> > from;

int main() {
    FILE *fi, *fout;
    int i, j, n;
    fi = fopen("nummst.in" ,"r");
    fout = fopen("nummst.out" ,"w");
    fscanf(fi,"%d " ,&n);
    int d = 2;
    while(n % d) {
        d++;
    }
    if(d == 2) {
        fprintf(fout,"%d %d\n" ,n / 2,n / 2);
        return 0;
    }
    int cnt = 0;
    for(i = 2; i <= d; i++) {
        if(low[i] == 0) {
            cnt++;
            for(j = i; j <= d; j += i) {
                low[j] = i;
            }
        }
    }
    dp.resize(cnt + 1);
    for(auto &it : dp) {
        it.resize(d + 1);
    }
    from.resize(cnt + 1);
    for(auto &it : from) {
        it.resize(d + 1);
    }
    for(i = 1; i <= d; i++) {
        dp[0][i] = -INF;
    }
    int ind = 0;
    for(i = 2; i < d; i++) {
        if(low[i] == i) {
            ind++;
            for(j = 1; j <= d; j++) {
                dp[ind][j] = dp[ind - 1][j];
                from[ind][j] = j;
            }
            int pw = i;
            float lg = log(1.0 * i);
            cnt = 0;
            while(pw <= d) {
                cnt++;
                for(j = pw; j <= d; j++) {
                    if(dp[ind][j] < dp[ind - 1][j - pw] + 1.0 * lg * cnt) {
                        dp[ind][j] = dp[ind - 1][j - pw] + 1.0 * lg * cnt;
                        from[ind][j] = j - pw;
                    }
                }
                pw *= i;
            }
        }
    }
    float ans = -1.0;
    int pos;
    for(i = 1; i <= d; i++) {
        if(ans < dp[ind][i]) {
            ans = dp[ind][i];
            pos = i;
        }
    }
    int aux = n;
    while(pos > 0) {
        if(from[ind][pos] != pos) {
            fprintf(fout,"%d " ,(n / d) * (pos - from[ind][pos]));
        }
        aux -= (n / d) * (pos - from[ind][pos]);
        pos = from[ind][pos];
        ind--;
    }
    while(aux > 0) {
        fprintf(fout,"%d " ,n / d);
        aux -= (n / d);
    }
    fclose(fi);
    fclose(fout);
    return 0;
}