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 ; }