codeforces #290 div1 B(DP / 暴力)

2015-02-03 16:12:22

思路:比赛中用暴力过掉的....后来发现正解是DP...

  First,我们发现只要找出k个数,使得Gcd(num1,num2,...,numk) = 1,就能达到每一个点。

       简证:如果我们只考虑两个数x,y。那么若 ax + by = 1 有整数解组a,b,那么就能达到每一个点。

        那么有贝祖定理:(a,b)代表最大公因数,则设a,b是不全为零的整数,则存在整数x,y,使得ax+by=(a,b)

        所以我们只要使得gcd(a,b)== 1即可。拓展到k个数的情况就是使得Gcd(num1,num2...numk) = 1

  Second,YY到gcd的个数应该不会很多,所以就开一个set,从1~n逐个考虑每个数,先将第i个数与set里面的所有数求一遍gcd,然后再把自己加入set... 以此类推。

     关于记录最优解,可以用map... (暴力过掉辣... 出题人真良心)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define MP(a,b) make_pair(a,b)
21 
22 typedef long long ll;
23 typedef pair<int,int> pii;
24 const int INF = (1 << 30) - 1;
25 
26 set<int> st;
27 map<int,int> mp;
28 
29 int Gcd(int a,int b){
30     return b == 0 ? a : Gcd(b,a % b);
31 }
32 
33 int n,l[310],c[310];
34 
35 int main(){
36     scanf("%d",&n);
37     REP(i,n) scanf("%d",&l[i]);
38     REP(i,n) scanf("%d",&c[i]);
39     REP(i,n){
40         set<int>::iterator it;
41         for(it = st.begin(); it != st.end(); ++it){
42             int g = Gcd(l[i],(*it));
43             st.insert(g);
44             if(mp.find(g) == mp.end())
45                 mp[g] = mp[(*it)] + c[i];
46             else
47                 mp[g] = min(mp[g],mp[(*it)] + c[i]);
48         }
49         st.insert(l[i]);
50         if(mp.find(l[i]) == mp.end())
51             mp[l[i]] = c[i];
52         else
53             mp[l[i]] = min(mp[l[i]],c[i]);
54     }
55     if(mp[1] == 0) printf("-1\n");
56     else printf("%d\n",mp[1]);
57     return 0;
58 }

 

posted @ 2015-02-03 20:24  Naturain  阅读(114)  评论(0编辑  收藏  举报