teoria dos números - Teorema Shu Pei

Shu Pei Teorema

Definir a, b é um número inteiro de nem todos os zeros, então os números inteiros X, Y , de tal modo que X + B * * Um Y = GCD (a, b)  .

prova ligeiramente

aplicação

Dá os n cartões, respectivamente, li e IC . Em uma fita infinitamente longo, você pode optar por passar ci  dinheiro para comprar o cartão i , em seguida, à esquerda ou você pode saltar li certas unidades. Pergunte quantos dólares você gasta pelo menos ser capaz de ignorar todas as posições na fita. Se não, a saída de -1 .

resolução:

Análise do problema, considere o caso de dois números e descobriu que você quer saltar em cada grade, devemos fazer esses números várias vezes, adicionando ou derivado, adicionando o valor absoluto de 1  , e depois pensou em Pei Shu teorema.

Libertação pode ser: Se um e b são relativamente primos, então deve haver dois números inteiros x e Y , de tal modo que por = 1 + AX.  .

Segue-se que, se o número de cartão selecionado várias vezes adicionando ou subtraindo um valor absoluto de 1 é obtido , então a constante número primo, este tempo pode ser considerado para a solução de programação dinâmica.

Mas as idéias podem ser transferidos, uma vez que estes número primo, 0 é o número de nós iniciantes, todos os passos necessários  mdc (número de nó, o próximo nó), durante a gravação do custo, tornou-se a partir de 0  através gcd contínua , finalmente, torna-se um mínimo preço.

Desde:. Primordial é o maior fator comum 1 , GCD (0, X) = X  estes dois teoremas, o algoritmo pode ser provada correta. Selecione a otimização fila de prioridade Dijkstra resolvido.

Mas há um problema, isto é, se a necessidade de gravar já comprou um cartão, tag array aberto, porque o intervalo de dados de até  10 ^ 9 excederia o limite de memória, é concebível para uso unordered_map 

#include <cstdio> 
#include <cstring> 
#include <algorithm> 
#include <cmath>  
#include <map> 
#include <queue> 
#include < seqüência >  
#include <iostream> 
#include <pilha>
 #define ll longa, longa
 #define inf 0x3f3f3f3f 
template < class T> em linha vazio gmax (T & a, T b) { se (b> a) a = b;}
template < class T> em linha vazio gmin (T & A, T b) { se (b <a) a = b;}
 usando  namespace std;
const  int N = 303 , M = 0 , Z = 1E9 + 7 , maxint = 2147483647 , MS31 = 522133279 , MS63 = 1061109567 , ms127 = 2139062143 ;
const  duplas eps = 1E- 8 , PI = acos (- 1.0 ); // 0,0 
mapa < int , int > mop;
mapear < você , você > :: iterator-lo;
você para [N], c [N];
você n;
você GCD ( que você começa, você y)
{
    int z;
    enquanto (y)
    {
        z = x% y;
        x = y;
        y = z;
    }
    return x;
}
int main ()
{
    enquanto (~ scanf ( " % d " , & n))
    {
        mop.clear ();
        para ( int i = 1 ; i <= n; i ++) scanf ( " % d " , & L [i]);
        para ( int i = 1 ; i <= n; i ++) scanf ( " % d " , & c [i]);
        para ( int i = 1 ; i <= n; i ++ )
        {
            para (it = mop.begin (); it = mop.end (!);-lo ++ )
            {
                int x = it-> em primeiro lugar;
                int y = it-> segundo;
                int g = GCD (L [i], x);
                se (mop.find (g) == mop.end ()) esfregão [g] = Y + C [i];
                mais gmin (esfregão [g], y + C [i]);
            }
            se (mop.find (L [i]) == mop.end ()) esfregão [l [i]] = c [i];
            mais gmin (esfregão [l [i]], C [i]);
        }
        se (mop.find ( 1 ) == mop.end ()) printf ( " -1 \ n " );
        mais printf ( " % d \ n " , esfregão [ 1 ]);
    }
    retornar  0 ;
}

 

Acho que você gosta

Origin www.cnblogs.com/2462478392Lee/p/12459710.html
Recomendado
Clasificación