1.题目描述:点击打开链接
2.解题思路:本题利用扫描与维护解决。根据题意,能够走到所有的格子,一定是挑选出来的牌的步数的最大公约是1,这点很好理解。因为ax+by=1意味着只要有a个x和b个y就可以凑出来步数1。这样以来,只需要利用map来存储所有的公约数对应的最小费用即可。初始时刻base[0]=0,接下来就是从前往后扫描一遍这n个数,然后依次更新base中的每一个最大公约是对应的最小费用即可。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define N 300+10 map<int, int>base; int L[N], C[N]; int n; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } int main() { //freopen("t.txt", "r", stdin); while (~scanf("%d", &n)) { base.clear(); for (int i = 0; i < n; i++) scanf("%d", &L[i]); for (int i = 0; i < n; i++) scanf("%d", &C[i]); map<int, int>::iterator it; base[0] = 0; for (int i = 0; i < n;i++)//考察每一张牌 for (it = base.begin(); it != base.end(); it++)//更新每一个最大公约数对应的最小费用 { int gmin = it->first, sumv = it->second; int g = gcd(gmin,L[i]); if (base.count(g))//存在最大公约数 base[g] = min(base[g], sumv + C[i]);//更新它的最小费用 else base[g] = sumv + C[i];//不存在该最大公约数 } if (!base.count(1)) printf("-1\n"); else printf("%d\n", base[1]); } return 0; }
时间: 2024-10-13 05:05:56