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] );
    }
}

你可能感兴趣的:(dp,数论,codeforces)