列表

详情


NC232854. 猫猫跳

描述

有一只猫猫想要从位置0开始在一条有无限多格(编号可能是任意整数)的道路上随意游走,但慢慢走实在是太慢了。这时,猫猫收到了霍格沃茨的雪鸮送来的n张魔法卡,每张魔法卡需要花费c_i的时间学习,学习之后可以快速移动l_i的距离,即从x(x-l_i)。猫猫准备学习若干个魔法,并依靠所学的魔法快速走遍这条道路。

猫猫想要尽快学会魔法实现自己的愿望,你可以帮猫猫求出最短的学习时间吗?

输入描述

第一行输入一个整数n (),表示魔法卡的数量。
第二行输入n个整数l_i (),表示每张魔法卡的移动距离。
第三行输入n个整数c_i (),表示学习每张魔法卡所需要的时间。

输出描述

如果可以通过学习若干个魔法实现快速走遍道路,则输出猫猫学习魔法的最短时间花费,否则输出-1

示例1

输入:

3
100 99 9900
1 1 1

输出:

2

说明:

选择100和99两个魔法卡即为需要时间最短的方案。

示例2

输入:

5
10 20 30 40 50
1 1 1 1 1

输出:

-1

说明:

编号不是10的倍数的格子无论如何也无法到达,所以输出-1。

示例3

输入:

7
15015 10010 6006 4290 2730 2310 1
1 1 1 1 1 1 10

输出:

6

示例4

输入:

8
4264 4921 6321 6984 2316 8432 6120 1026
4264 4921 6321 6984 2316 8432 6120 1026

输出:

7237

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 14ms, 内存消耗: 484K, 提交时间: 2022-11-21 17:11:12

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
const int N=310;
map<int,ll> dp,back;
PII a[N];
int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int len;
    cin>>len;
    for(int i=1;i<=len;i++){
        cin>>a[i].first;
    }
    for(int i=1;i<=len;i++){
        cin>>a[i].second;
    }
    for(int i=1;i<=len;i++){
        ll q=a[i].first,w=a[i].second;
        back=dp;
        if(!dp.count(q)) dp[q]=w;
        else dp[q]=min(dp[q],w);
        for(auto &[i,j]:back){
            int p=gcd(i,q);
            if(!dp.count(p)) dp[p]=j+w;
            else dp[p]=min(dp[p],j+w);
        }
    }
    if(dp.count(1)) cout<<dp[1];
    else cout<<-1;
}

C++(clang++ 11.0.1) 解法, 执行用时: 11ms, 内存消耗: 448K, 提交时间: 2023-07-09 19:50:18

#include<bits/stdc++.h>
using namespace std;
int n,a[302],b[302];
map<int,int> f;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    f[0]=0;
    for(int i=1;i<=n;++i){
        for(auto &[k,v]:f){
            int x=__gcd(k,a[i]);
            if(f[x]) f[x]=min(f[x],f[k]+b[i]);
            else f[x]=f[k]+b[i];
        }
    }
    cout<<(f[1]?f[1]:-1);
}

上一题