CF290-D

给定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