本题得知道一个结论,如果序列里面的数的最大公约数为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; }