Codeforcres 510D Fox And Jumping (数论+dp)

本文详细解析了Codeforces平台上的510-D问题,该问题是关于如何通过选择特定属性的卡牌以最小的成本覆盖所有可能的位置。通过应用数学定理和动态规划方法,本文提供了一个简洁且高效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/problemset/problem/510/D


题意:有N张卡牌,每张卡牌有属性l和cost,选择一张卡牌后需要花费cost,可以走l距离(卡牌选择后可以多次使用),问如何花费最小可以走到任何地方


思路:要走到任何地方也就是要卡牌组合成1(如选择l=3和l=2的2张卡牌),这里有一个数学定理,gcd(a,b)=1则代表可以用a和b组合出任意的数(如果不等于1大概就是表示可以组成的最小的数),通过枚举所有卡牌更新可以组合出的所有数的最小值就可以(看了别人的代码用了map来写dp很简介……学习了下)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define maxn 330
#define LL long long
using namespace std;

map <LL,LL> mp;

LL cost[maxn],val[maxn];

LL gcd(LL a,LL b)
{
    if (a<b) swap(a,b);
    if (b!=0) return gcd(b,a%b);
    else return a;
}

int main()
{
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        mp.clear();
        for (int i=0;i<n;i++)
        {
            scanf("%I64d",&val[i]);
        }

        for (int i=0;i<n;i++)
        {
            scanf("%I64d",&cost[i]);
        }

        mp[0]=0;
        map <LL,LL>::iterator it;
        for (int i=0;i<n;i++)
        {
            for (it=mp.begin();it!=mp.end();it++)
            {
                int x=it->first;
                int y=it->second;
                LL tem=gcd(x,val[i]);//cout<<mp.count(tem)<<":";
                if (mp.count(tem)) mp[tem]=min(mp[tem],y+cost[i]);
                else mp[tem]=y+cost[i];
            }//cout<<endl;
        }


        if (mp.count(1)) printf("%I64d\n",mp[1]);
        else printf("-1\n");
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值