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