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

题目链接:

codeforces


题目大意:

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


题目分析:

  • 其实题意就是用最小的花费去拼凑出1。有了1就能得到所有自然数,而且1也是必须要凑出来的。
  • 因为任意几个数能够凑出的最小的数是他们的gcd.
  • 所以我们利用map存在某个gcd的最小值,然后最后求出gcd为1的最小花费。

AC代码:

#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] );
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值