codeforces510D Fox And Jumping gcd

题意:n张卡,可跳跃的长度l[i],以及花费c[i]

起始点为0,问如果选卡使得可以每个点都能跳到,最小的花费是多少。

思路:本质就是选取一些卡,选择卡长度的gcd为1,且花费最小。那么我们用map映射gcd值以及其对应的最小花费。最后输出mp[1]即可。(ps:可能有卡片长度相同)详见代码:

/*********************************************************
  file name: codeforces510D.cpp
  author : kereo
  create time:  2015年02月03日 星期二 16时25分06秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=300+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n;
int a[MAXN],c[MAXN];
map<int,int>mp; //记录gcd值为x对应的最小的代价
vector<int>vec;
int gcd(int a,int b){
    return b == 0 ? a : gcd(b,a%b);
}
int main(){
    while(~scanf("%d",&n)){
        mp.clear(); vec.clear();
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        int res=a[1];
        for(int i=2;i<=n;i++)
            res=gcd(res,a[i]);
        if(res!=1){
            printf("-1\n");
            continue;
        }
        for(int i=1;i<=n;i++){
            if(mp[a[i]] == 0){
                mp[a[i]]=c[i];
                vec.push_back(a[i]);
            }
            else if(mp[a[i]]>c[i])
                mp[a[i]]=c[i];
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<vec.size();j++){
                int tmp=gcd(a[i],vec[j]);
                if(mp[tmp] == 0){
                    vec.push_back(tmp);
                    mp[tmp]=mp[vec[j]]+mp[a[i]];
                }
                else if(mp[tmp]>mp[vec[j]]+mp[a[i]])
                    mp[tmp]=mp[vec[j]]+mp[a[i]];
            }
        }
        printf("%d\n",mp[1]);
    }
	return 0;
}
时间: 2024-11-05 13:29:49

codeforces510D Fox And Jumping gcd的相关文章

Fox And Jumping

Fox And Jumping 题目链接:http://codeforces.com/problemset/problem/512/B dp 若所选卡片能到达区间内任意点,那么所选卡片的最大公约数为1(a*x+b*y=gcd(a,b)=1). 定义状态dp[i]:获得i需要的最小的代价. 代码如下: 1 #include<cstdio> 2 #include<map> 3 #include<iostream> 4 #define LL long long 5 using

Codeforces 512B Fox And Jumping dp+gcd

题目链接:点击打开链接 题意: 给定n个数 下面2行是n个数字和购买该数字的花费. 使得购买的数字能通过加减获得任意一个正整数.问最小的花费是多少.(购买得到的数字可以多次使用) 思路: 首先是要获得任意的正整数,其实就是获得1就可以了. 而获得1的话 只需要我们选的数的gcd = 1即可. 设 有整数x,y,要使得x y能构造任意一个整数,充要条件就是gcd(x, y)=1 推论: 设int G = gcd(x, y); 则 ax+by = G( ax/G+by/G ) 括号中能构成任意一个整

#290 (div.2) D. Fox And Jumping

1.题目描述:点击打开链接 2.解题思路:本题利用扫描与维护解决.根据题意,能够走到所有的格子,一定是挑选出来的牌的步数的最大公约是1,这点很好理解.因为ax+by=1意味着只要有a个x和b个y就可以凑出来步数1.这样以来,只需要利用map来存储所有的公约数对应的最小费用即可.初始时刻base[0]=0,接下来就是从前往后扫描一遍这n个数,然后依次更新base中的每一个最大公约是对应的最小费用即可. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<i

Codeforces_512B: Fox And Jumping

题目链接 题意说的是,有n种卡片,使用第i种卡片可以使当前自己在数轴上的位置移动 l[i],要获得使用第i种卡片的代价是 c[i],求能使自己移动到数轴上任意位置的最小代价,如果不可能则输出-1 当前所拥有的卡片由1->n,逐渐调整map里的值 #include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n; int c[N],l[N]; map<int,int> dp; int gcd(int a,

【Codeforces 290 B】Fox And Jumping

根据裴蜀定理,当且仅当选出来的集合的L[i]的gcd等于1时,才能表示任何数. 考虑普通的dp,dp[i][j]表示前i个数gcd为j的最少花费,j比较大,但状态数不多,拿个map转移就好了. 技巧&套路: 裴蜀定理,gcd为1表示任何数. 当状态数不多的时候,map暴力转移dp. 1 #include <cstdio> 2 #include <map> 3 #include <algorithm> 4 5 const int N = 305; 6 7 int

[Codeforces#510D] Fox And Jumping

Codeforces题号:#510D 出处: Codeforces 主要算法:贪心+优先队列 难度:4.6 思路分析: 题意:给出n张卡片,分别有l[i]和c[i].在一条无限长的纸带上,你可以选择花c[i]的钱来购买卡片i,从此以后可以向左或向右条l[i]个单位.购买其他卡片后,可以获得更多的跳跃单位.先要求至少花多少元钱才能够任意跳到纸带上任意一个位置.若不行,输出-1. 首先分析如果只有两个技能的情况.若这两个技能的跳跃长度有最大公约数(x),且满足(x > 1),则一定能跳到任意一个位置

所谓的日常 #7 - 袁紹磐河戰公孫 孫堅跨江擊劉表

div.2 CodeForces 334A Candy Bags 给定一个偶数n(<=100),把价值为1~n^2的糖们分发给n个小朋友,使得大家手上糖的总价值一样. 考虑这样配对:(1,n^2),(2,n^2-1),(3,n^2-2)...(i,n^2-i+1).每对价值和都是n^2+1,总共有n^2/2对,按对分给小朋友就好啦. 1 #include <stdio.h> 2 3 int main() { 4 int n; 5 scanf("%d",&n);

Codeforces Round #290 (Div. 2) 解题报告 A.B.C.D.

A - Fox And Snake 模拟. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using na

裴蜀定理巧用最短路

定义 \(x,y\) 的不定方程 \(ax + by = c\) 有整数解的充要条件是 \(\gcd(a, b)\mid c\) . 即为如果\(a\)与\(b\)互质,那么一定存在两个整数\(x\)与\(y\),使得\(ax+by=1\). 详见Wikiwand-斐蜀定理 例题 Codeforces Round #290 (Div. 2) D. Fox And Jumping 翻译 给出\(n\)张卡片,分别有\(l_i\)和\(c_i\).在一条无限长的纸带上,你可以选择花\(c_i\)的钱