【题解】Fox And Jumping

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GiKCKoVM-1607157569836)(C:\Users\Stuedent\AppData\Roaming\Typora\typora-user-images\image-20201031190305068.png)]

根据某个(裴蜀)定理,有以下结论:

a x + b y = g c d ( a , b ) , 存 在 一 组 x , y 使 该 式 成 立 ax+by=gcd(a,b),存在一组x,y使该式成立 ax+by=gcd(a,b),x,y使

显然,当 g c d ( a , b ) = X gcd(a,b)=X gcd(a,b)=X的时候,能够跳到所有倍数是 X X X的格子。

因此,当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1的时候,我们能够跳到所有的格子。

这个可以推广到 n n n个数。

于是,题目便转化成从 n n n个数中选取若 k k k个数,使得 g c d ( l 1 , l 2 … … , l k ) = 1 gcd(l_1,l_2……,l_k)=1 gcd(l1,l2,lk)=1,并且 ∑ i = 1 k c i \sum_{i=1}^k c_i i=1kci最小

我们又 g c d = 1 gcd=1 gcd=1这一个强力的限制条件,因此我们可以做一遍 g c d gcd gcddp(背包)

f [ i ] f[i] f[i]表示 g c d gcd gcd i i i时的最小代价。答案显然就是 f [ 1 ] f[1] f[1]

考虑转移。枚举每一个数的时候,将 l [ i ] l[i] l[i]与之前所有出现过得 g c d ( j ) gcd(j) gcd(j)一一求一遍 g c d ( X ) gcd(X) gcd(X),于是就用 f [ j ] + c [ i ] f[j]+c[i] f[j]+c[i]来更新 f [ t m p ] f[tmp] f[tmp]


补充一个 M a p Map Map小知识。

如果你想访问 M a p Map Map,可以用迭代器来访问。

定义如下:

map < int , int > :: iterator it;

遍历的话用一下形势:

it = M.begin()
for (; it!=M.end(); ++it)
  it->first//M的定义域
  it->second//映射对应的值

由于本题的值域较大,数组无法存储,因此要用map代替数组进行dp


Code

#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N = 2e5+10;

int n;
int l[N],c[N];
map < int , int > M;
int Min = 1e15+7;

int gcd(int x,int y){return y == 0?x:gcd(y,x%y);}

signed main(){
	scanf("%lld",&n);
	for (int i = 1; i <= n; i++) scanf("%lld",&l[i]);
	for (int i = 1; i <= n; i++) scanf("%lld",&c[i]);
	M[0] = 0;
	for (int i = 1; i <= n; i++){
		int Gc;
		map < int , int > :: iterator it = M.begin();
		for (;it != M.end(); ++it){
			Gc = gcd(l[i],it->first);
			if (M[Gc] == 0) M[Gc] = it->second+c[i];
			else M[Gc] = min(M[Gc],it->second+c[i]);
			if (Gc == 1) Min = min(Min,M[Gc]);
		}
	}
//	if (M.count(1)) cout<<1;else cout<<0;
	if (Min == 1e15+7) printf("-1");else printf("%lld",Min);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值