Luogu P2618 Digital Engineering

DP

The following tips based on the title & description, we can know the general idea to do this problem: first find out the prime factors of each number, and then began to DP.

New Method for prime factor is similar to the Euler screen operation, if a number has not been to be screened, then ta is a prime number, then we can use to continue ta number of other screens, and we only use ta is a multiple of the screen, because it contains only multiple ta is the prime factor, the number of the screen to mark marked must be timely Do not ask me whySo what we need to open an array of prime factors to record it? In fact, only about 23 can be used up, since the \ (2 ^ {20} = 1048576> 10 ^ 6 \) , the opening 23 is sufficient.

The last part of the DP is, as far as the two cases, the \ (i-1 \) or \ (i / prime_i \) transferred from the answer take a \ (min \) like, there is little problem of this input pit, concrete solutions was written on to the Ke:

while(scanf("%d",&n)!=EOF)printf("%d\n",f[n]);

Finally, I offeruglyCode

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000000,M=1000010;
int n;
int yz[M][23],num[N],f[M];
bool vis[M];
void yych()
{
    for(int i=2;i<=N;++i)
    if(!vis[i])
    for(int j=i;j<=N;j+=i)
    vis[j]=1,yz[j][++num[j]]=i;//注意vis 
    
    for(int i=2;i<=N;++i)//DP
    {
        f[i]=f[i-1]+1;
        for(int j=1;j<=num[i];++j)f[i]=min(f[i],f[i/yz[i][j]]+1);
    }
}
int main()
{
    yych();
    while(scanf("%d",&n)!=EOF)printf("%d\n",f[n]);//scanf存在返回值,当不再输入的时候就会返回EOF 
}

Guess you like

Origin www.cnblogs.com/wljss/p/11537074.html