Number theory - Theorem Shu Pei

Shu Pei Theorem

Set a, b is an integer of not all zeros, then the integers X, Y , such that X + B * * A Y = GCD (a, b)  .

Proof slightly

application

Gives the n cards, respectively, li and CI . On an infinitely long tape, you can choose to spend ci  money to buy the card i , then on the left or you can jump right li units. Ask how many dollars you spend at least be able to skip all positions on the tape. If not, the output of -1 .

Resolution:

Analysis of the problem, consider the case of two numbers and found that you want to jump on each grid, we must make these numbers several times by adding or derived by adding the absolute value of 1  , and then thought of Pei Shu theorem.

Release can be: if a and b are relatively prime, then there must be two integers x and Y , such that by =. 1 + AX  .

It follows that if the number of the selected card several times by adding or subtracting an absolute value of 1 is obtained , then the prime number constant, this time can be considered for solving dynamic programming.

But ideas can be transferred, since these prime number, 0 is the number of nodes beginning, every step required  gcd (node number, the next node), while recording the cost, became from 0  through continuous gcd finally becomes a minimum cost.

Since: prime is the greatest common factor. 1 , GCD (0, X) = X  these two theorems, the algorithm can be proved correct. Select the priority queue optimization Dijkstra solved.

But there is a problem, that is, whether the need to record already bought a card, open array tag because the data range of up to  10 ^ 9 would exceed the memory limit, it is conceivable to use unordered_map 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath> 
#include<map>
#include<queue>
#include<string> 
#include<iostream>
#include<stack>
#define ll long long
#define inf 0x3f3f3f3f
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=303,M=0,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;
const double eps=1e-8,PI=acos(-1.0);//.0
map<int,int>mop;
map<int,int>::iterator it;
int l[N],c[N];
int n;
int gcd(int x,int y)
{
    int z;
    while(y)
    {
        z=x%y;
        x=y;
        y=z;
    }
    return x;
}
int main()
{
    while(~scanf("%d",&n))
    {
        mop.clear();
        for(int i=1;i<=n;i++)scanf("%d",&l[i]);
        for(int i=1;i<=n;i++)scanf("%d",&c[i]);
        for(int i=1;i<=n;i++)
        {
            for(it=mop.begin();it!=mop.end();it++)
            {
                int x=it->first;
                int y=it->second;
                int g=gcd(l[i],x);
                if(mop.find(g)==mop.end())mop[g]=y+c[i];
                else gmin(mop[g],y+c[i]);
            }
            if(mop.find(l[i])==mop.end())mop[l[i]]=c[i];
            else gmin(mop[l[i]],c[i]);
        }
        if(mop.find(1)==mop.end())printf("-1\n");
        else printf("%d\n",mop[1]);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/2462478392Lee/p/12459710.html