题目链接:
题目大意:
给出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] );
}
}