codeforces 510D D. Fox And Jumping(dp+数论)

58 篇文章 0 订阅

题目链接:

codeforces


题目大意:

给出n张卡,每张卡可以用无限次,每种卡需要 Ci 的花费,问最少用多少花费,能够组成所有的自然数。


题目分析:

  • 其实题意就是用最小的花费去拼凑出1。有了1就能得到所有自然数,而且1也是必须要凑出来的。
  • 因为任意几个数能够凑出的最小的数是他们的gcd.
  • 所以我们利用map存在某个gcd的最小值,然后最后求出gcd为1的最小花费。 
  • #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <map>
    #define MAX 307
    
    using namespace std;
    typedef pair<int,int> PII;
    typedef map<int,int> MII;
    
    int n;
    MII dp;
    PII a[MAX];
    
    int gcd ( int a , int b )
    {
        return !b?a:gcd ( b , a%b );
    }
    
    int main ( )
    {
        while ( ~scanf ("%d" , &n ) )
        {
            for ( int i = 0 ; i < n ; i++ )
                scanf ( "%d" , &a[i].first );
            for ( int i = 0 ; i < n ; i++ )
                scanf ( "%d" , &a[i].second );
            dp.clear();
            MII::iterator it;
            dp[0] = 0;
            for ( int i = 0; i < n ; i++ )
            {
                int x = a[i].first;
                int c = a[i].second;
                for ( it = dp.begin() ; it != dp.end() ; it++ )
                {
                    int y = it->first;
                    int d = gcd ( x , y );
                    int temp = it->second+c;
                    if ( dp[d] && dp[d] < temp ) continue;
                    dp[d] = temp;
                }
            }
            if ( !dp[1] ) puts ( "-1" );
            else printf ( "%d\n" , dp[1] );
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值