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");elseprintf("%d\n",mp[pre][1]);}

走走停停,不要害怕错过什么,

Codeforces 512B Fox And Jumping dp+gcd

相关文章:

你感兴趣的文章:

标签云: