Cod sursa(job #968607)

Utilizator geniucosOncescu Costin geniucos Data 2 iulie 2013 12:57:38
Problema NumMst Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int pz,expo,prod,nr,n,i,j,cmmdc,obt[509][3209],pr[509];
char cr[3209];
double lg,maxi,dp[2][3209];
vector < int > v;
vector < int > ::iterator it;
int main()
{
freopen("nummst.in","r",stdin);
freopen("nummst.out","w",stdout);
scanf("%d",&n);
for(i=2;i*i<=n;i++)
if(n%i==0)
{
    if(n/i>cmmdc) cmmdc=n/i;
    if(i>cmmdc) cmmdc=i;
}
n/=cmmdc;
if(n==2)
{
    printf("%d %d\n",cmmdc,cmmdc);
    return 0;
}
if(n==3)
{
    printf("%d %d\n",cmmdc,2*cmmdc);
    return 0;
}
if(n==4)
{
    printf("%d %d\n",cmmdc,3*cmmdc);
    return 0;
}
for(i=2;i*i<=n;i++)
    if(cr[i]==0)
    {
        for(j=i*i;j<=n;j+=i)
            cr[j]=1;
    }
////fac dinamica dp[i][j]=cmmdc-ul maxim care se poate obtine cu suma j, folosind doar factori primi din primele j numere prime
for(i=2;i<=n;i++)
if(cr[i]==0)
{
    nr++;
    pr[nr]=i;
}
dp[0][0]=(double)log(1);
for(j=1;j<=n;j++)
    dp[0][j]=-12345678910;
for(i=1;i<=nr;i++)
{
    lg=(double)log(pr[i]);
    for(j=0;j<=n;j++)
        dp[i&1][j]=dp[(i&1)^1][j];
    for(j=0;j<=n;j++)
    {
        prod=1;
        for(expo=0;prod+j<=n;expo++)
        {
            if((double)dp[(i&1)^1][j]+expo*lg>(double)dp[i&1][j+prod])
            {
                dp[i&1][j+prod]=(double)dp[(i&1)^1][j]+expo*lg;
                obt[i][j+prod]=prod;
            }
            prod*=pr[i];
        }
    }
}
maxi=0;
for(j=0;j<=n;j++)
    if(dp[nr&1][j]>maxi)
    {
        maxi=dp[n&1][j];
        pz=j;
    }
j=pz;
if(j!=n) v.push_back(n-j);
n-=j;
i=nr;
while(i)
{
    if(obt[i][j]!=0) v.push_back(obt[i][j]);
    j-=obt[i][j];
    i--;
}
sort(v.begin(),v.end());
for(it=v.begin();it!=v.end();it++)
    printf("%d ",*it*cmmdc);
return 0;
}