Fox And Jumping CodeForces - 510D(数论&记忆化搜索)

Fox And Jumping CodeForces - 510D

http://codeforces.com/contest/510/problem/D

题目大意

给出n个片段( n ≤ 300 n\le 300 n300)每个片段有一定的长度与价值,购买下一个片段后可以在任意位置x通往x+l或x-l处,l为片段的长度,问最少需要花费多少钱才可以保证可以到达任意一个坐标点

解题思路

题目大意即为求花费尽可能少的地买下一些片段使片段长度的gcd=1

考虑到n个片段的gcd至多有 n 2 n^2 n2个因此直接对所有能就构成的gcd进行记忆化搜索搜索,得出得到所有gcd的最小花费

AC代码

#include<bits/stdc++.h>
#define int long long 
using namespace std;
typedef long long LL;
int len[305],cost[305];
unordered_map<int,LL> mp;
queue<int> q;
LL gcd(LL a,LL b)
{
	return b==0?a:gcd(b,a%b);
}
int32_t main()
{
	int n;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++) cin>>len[i];
	for(int i=1;i<=n;i++) cin>>cost[i];
	for(int i=1;i<=n;i++)
	{
		if(mp.count(len[i])!=0) mp[len[i]]=min(cost[i],mp[len[i]]);
		else
		{
			mp[len[i]]=cost[i];
			q.push(len[i]);
		}
	}
	while(!q.empty())
	{
		int temp=q.front();q.pop();
		for(int i=1;i<=n;i++)
		{
			int t=gcd(temp,len[i]);
			if(mp.count(t))mp[t]=min(mp[t],mp[temp]+cost[i]);
			else mp[t]=mp[temp]+cost[i],q.push(t);
		}
	}
	if(!mp.count(1)) cout<<-1<<endl;
	else 
	cout<<mp[1]<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值