首页 > 代码库 > Codeforces 512B Fox And Jumping dp+gcd
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 )
括号中能构成任意一个整数, 当G=1时才能使得ax+by 能组成1。
然后就是动态维护集合中每个gcd对应的最小花费。
#include <cstdio> #include <cstring> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include <vector> #include <cmath> #include <set> #include <map> using namespace std; int l[306]; int c[306]; int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } map<int,int>mp[2]; map<int,int>::iterator it; int pre,cur; int hehe; int papa; void setMin(int x,int y) { if(mp[cur].count(x)) { if(y<mp[cur][x]) mp[cur][x]=y; } else mp[cur][x]=y; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&l[i]); for(int i=1;i<=n;i++) scanf("%d",&c[i]); pre=0;cur=1; mp[0][l[1]]=c[1]; for(int i=2;i<=n;i++) { mp[cur].clear(); mp[cur][l[i]]=c[i]; for(it=mp[pre].begin();it!=mp[pre].end();it++) { int x=it->first; int y=it->second; setMin(x,y); setMin(gcd(x,l[i]),y+c[i]); } swap(pre,cur); } if(!mp[pre].count(1)) puts("-1"); else printf("%d\n",mp[pre][1]); }
Codeforces 512B Fox And Jumping dp+gcd
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。