给定n个跳跃卡片,卡片中有距离和相应的代价,初始的位置为0,问至少需要多少代价可以跳至任意的位置.
如跳跃10距离的代价为1,那么花费1的代价可以跳至10倍数的任意地方.
要跳至任意距离很容易就想到将所有的卡片组合成能跳跃1距离的"大卡片"
两张卡片能组合成的"大卡片"跳跃距离最小是这两张卡片的最大公约数
对前1至前n张卡片进行遍历,求出能组合成‘新距离‘的最小代价
状态转移方程 dp[k]=min(dp[k],dp[j]+cost[i]) 其中k=gcd(j,i)
#include <iostream> using namespace std; #include <map> int gcd(long long a,long long b) { return b==0?a:gcd(b,a%b); } int main() { map<int,int> dp; int n; int cost[500]; int lenth[500]; cin>>n; for(int i=1;i<=n;i++) { cin>>lenth[i]; } for(int i=1;i<=n;i++) { cin>>cost[i]; } dp[0]=0; for(int i=1;i<=n;i++) { map<int,int>::iterator it=dp.begin(); for(;it!=dp.end();it++) { int t=gcd(lenth[i],it->first); if(dp.count(t)) { dp[t]=min(dp[t],cost[i]+it->second); } else { dp[t]=cost[i]+it->second; } } } if(dp.count(1)) cout<<dp[1]<<endl; else cout<<"-1"<<endl; return 0; }
时间: 2024-11-22 19:53:10