Prueba java B del décimo Campeonato Nacional: división de números primos

División de números primos


Dividiendo 2019 en la suma de varios números primos diferentes, ¿cuántos métodos diferentes hay? Tenga en cuenta que el orden de intercambio se considera el mismo método, por ejemplo, 2 + 2017 = 2019 y 2017 + 2 = 2019 se consideran el mismo método.
Método 1
: La
misma idea que la mochila 01 excepto que se cuentan los resultados estadísticos, i es el número primo de 2019 a 2, yj es la posibilidad de 2019. f [0] [0] = 1 porque también es una posibilidad. f [i] [j] = f [i-1] [j] Esto es pasar la capa de f [i-1] [j] y luego f [i] [j] + = f [i-1] [ j-z1 [i]] es la acumulación de [j-z1 [i]] + f [i] [j] el resultado del nivel superior más el número posible de este nivel de números primos.

programa:

def z(a):
    if a==2 or a==3:
        return 1
    if a%2==0:
        return 0
    p=1
    while p*p<=a:
        p+=2
        if a%p==0:
            return 0
    return 1
z1=[0]
for i in range(2,2020):
    if z(i):
        z1.append(i)

f=[[0 for i in range(2023)]for i in range(2023)]

f[0][0]=1
for i in range(1,len(z1)):
    for j in range(0 ,2020):
        f[i][j]=f[i-1][j]
        if j>=z1[i]:
            f[i][j]+=f[i-1][j-z1[i]]
print(f[len(z1)-1  ][2019])

El método después de optimizar el espacio:
Idea:
Podemos usar el pensamiento unidimensional para resolver el problema.

def z(a):
    if a==2 or a==3:
        return 1
    if a%2==0:
        return 0
    p=1
    while p*p<=a:
        p+=2
        if a%p==0:
            return 0
    return 1
z1=[0]
for i in range(2,2020):
    if z(i):
        z1.append(i)

f=[0 for i in range(2023)]

f[0]=1
for i in range(1,len(z1)):
    for j in range(2019,z1[i]-1,-1):
        
        f[j]+=f[j-z1[i]]
print(f[2019])

Está prohibida la reimpresión. Solo para autoaprendizaje. No se hace responsable de los errores del programa.

Supongo que te gusta

Origin blog.csdn.net/weixin_46640345/article/details/112783161
Recomendado
Clasificación