# CodeForces 510D Fox And Jumping：DP+数论+离散（map 的奇技淫巧）

/ 1评 / 1

CodeForces 510D Fox And Jumping：510D

## Problem

Fox Ciel is playing a game. In this game there is an infinite long tape with cells indexed by integers (positive, negative and zero). At the beginning she is standing at the cell 0.

There are also n cards, each card has 2 attributes: length l_i and cost c_i. If she pays c_i dollars then she can apply i-th card. After applying i-th card she becomes able to make jumps of length l_i, i. e. from cell x to cell (x - l_i) or cell (x + l_i).

She wants to be able to jump to any cell on the tape (possibly, visiting some intermediate cells). For achieving this goal, she wants to buy some cards, paying as little money as possible.

If this is possible, calculate the minimal cost.

## Input

The first line contains an integer n (1 ≤ n ≤ 300), number of cards.

The second line contains n numbers l_i (1 ≤ l_i ≤ 10^9), the jump lengths of cards.

The third line contains n numbers c_i (1 ≤ c_i ≤ 105), the costs of cards.

## Output

If it is impossible to buy some cards and become able to jump to any cell, output -1. Otherwise output the minimal cost of buying such set of cards.

## Examples

### input #1

3
100 99 9900
1 1 1


### Output #1

2


### Input #2

5
10 20 30 40 50
1 1 1 1 1


### Output #2

-1


### Input #3

8
4264 4921 6321 6984 2316 8432 6120 1026
4264 4921 6321 6984 2316 8432 6120 1026


### Output #3

7237


## Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn=305;
int n,a[maxn],p[maxn],to[maxn*maxn],f[2][maxn][maxn*maxn],cnt=0,ans,INF;
map <int,int> back; // 为了压缩内存，建立映射关系 (离散)
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline int gcd(int x,int y){
if (y==0) return x;
return gcd(y,x%y);
}
int main(){
memset(f,63,sizeof(f));INF=f[0][0][0];
cnt++;to[cnt]=0;back[0]=cnt; // 建立基本映射单位的过程
f[0][0][1]=0;
for (int i=1;i<=n;i++)
for (int j=0;j<=i;j++){
int oldcnt=cnt;
for (int k=1;k<=oldcnt;k++){
if (f[1-(i&1)][j][k]<f[i&1][j][k]) f[i&1][j][k]=f[1-(i&1)][j][k];

if (j==0||f[1-(i&1)][j-1][k]==INF) continue;
int now=gcd(to[k],a[i]);
if (back[now]==0) {cnt++;to[cnt]=now;back[now]=cnt;}
int nowx=back[now];
if (f[1-(i&1)][j-1][k]+p[i] < f[i&1][j][nowx]) f[i&1][j][nowx]=f[1-(i&1)][j-1][k]+p[i];
}
}
ans=INF;int st=back[1];
if (st) for (int i=1;i<=n;i++) if (f[n&1][i][st]<ans) ans=f[n&1][i][st];
if (ans-INF) printf("%d\n",ans); else printf("-1\n");
return 0;
}


### 一条回应：“CodeForces 510D Fox And Jumping：DP+数论+离散（map 的奇技淫巧）”

1. ZigZagK说道：

都C++11了当然上unordered_map啦。

• 默认
• 护眼
• 夜晚
• Serif
• Sans