Codeforces Round #290 (Div. 2) D. Fox And Jumping(数论,裴蜀定理,gcd)

题目链接:https://codeforces.com/contest/510/problem/D

题意:

给你一些数,问能否用它们组成所有自然数,如果可以输出最小代价(一个数的代价只需计入一次)。

思路:

裴蜀定理(又名贝祖定理):存在$x$,$y$,使得$ax+by=gcd(a,b)$。

所以只需验证所有能组成的$gcd$中是否有$1$即可。

用$dp$记录组成每个数的最小代价,所求即$dp[1]$,由于数据过大可以用$map$。

Tips:

unordered_map虽然访问较快,但是由于其内部是用哈希表实现的,遍历时可能访问不全(找了一个小时的bug)。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;cin>>n;
    int a[n];for(int &i:a) cin>>i;
    int c[n];for(int &i:c) cin>>i;

    map<int,int> dp;

    for(int i=0;i<n;i++)
    {
        dp[a[i]]=dp[a[i]]?min(dp[a[i]],c[i]):c[i];

        for(auto j:dp)
        {
            int value=__gcd(a[i],j.first);
            int cost=dp[a[i]]+j.second;

            dp[value]=dp[value]?min(dp[value],cost):cost;
        }
    }

    cout<<(dp[1]?dp[1]:-1);

    return 0;
}

 

posted @ 2020-04-02 23:45  Kanoon  阅读(257)  评论(0编辑  收藏  举报