本题得知道一个结论,如果序列里面的数的最大公约数为1的话就一定可以到达任意一个魔法阵。
那么就对最大公约数进行动态规划。以每个数为外层循环。每一次都与前面有的或产生的数进行最大公约数的计算,然后更新某个数作为最大公约数所需要的花费即可。
//对于某一个数 它的加入对原来产生的影响是原来拥有的所有的数的花费。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 300+10;
int n;
int l[maxn], c[maxn];
map<int, int> dp;
vector<int> v;
int gcd(int a, int b) {
int c;
while (b) {
c = a%b;
a = b;
b = c;
}
return a;
}
signed main() {
cin>>n;
for (int i=1;i<=n;i++) {
cin>>l[i];
}
for (int i=1;i<=n;i++) {
cin>>c[i];
}
// for (int i=1;i<=n;i++) {
// dp[l[i]] = c[i];
// }
for (int i=1;i<=n;i++) {
// cout<<dp[l[i]]<<endl;
if (!dp[l[i]]) {
// cout<<"s="<<v.size()<<endl;
dp[l[i]] = c[i];
v.push_back(l[i]);
} else {
dp[l[i]] = min(dp[l[i]], c[i]);
// cout<<"dp[l[i]]="<<dp[l[i]]<<endl;
}
for (int j=0;j<v.size();j++) {
// cout<<j<<endl;
int gd = gcd(l[i], v[j]);
// cout<<"gd="<<gd<<endl;
if (!dp[gd]) {
dp[gd] = dp[v[j]]+dp[l[i]];
v.push_back(gd);
} else {
dp[gd] = min(dp[gd], dp[v[j]]+dp[l[i]]);
}
// cout<<"dp[gd]="<<dp[gd]<<endl;
}
}
if (dp[1]) cout<<dp[1]<<endl;
else cout<<-1<<endl;
return 0;
}

京公网安备 11010502036488号