CF - Fox And Jumping

原题: Problem - D - Codeforces

题意:给你一个数组,以及选择数组中数对应的花费。现要求从数组中选出部分数,使这些数的最大公约数为1,且花费最小,输出最终花费。

分析:

dp[i]表示使目前最大公约数为i的最小花费,由于数字较大,需要用map存储。

题解:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=305;
ll l[N],c[N];
map<ll,ll> dp;

int main()
{
    int n;
    cin>>n;

    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&l[i]);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&c[i]);
    }
    for(int i=1;i<=n;i++)
    {
        //往dp中加入l[i],判断使最大公约数变为l[i]的最小花费
        if(dp[l[i]]) dp[l[i]]=min(dp[l[i]],c[i]);
        else dp[l[i]]=c[i];
        
        //遍历dp数组,将每一个元素与l[i]求最大公约数并更新最小花费
        for(auto it:dp)
        {
            ll now=__gcd(l[i],it.first);//加入数l[i]的最大公约数
            ll cost=dp[l[i]]+it.second;//加入数后的花费

            if(dp[now]) dp[now]=min(dp[now],cost);
            else dp[now]=cost;
        }
    }

    if(dp[1]) cout<<dp[1];
    else cout<<"-1";
    return 0;
}
posted @ 2021-06-05 15:16  AtomsH  阅读(60)  评论(0)    收藏  举报