XJOI网上同步训练DAY5 T1

 

 思路:考虑得出,最终的集合一定是gcd=1的集合,那么我们枚举n个数中哪个数必须选,然后把它质因数分解,由于质数不会超过9个,可以状态压缩,去得出状态为0的dp值就是答案。

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 int n,l[305],c[305],p[3005],val[30005],f[305][1025];
 7 int read(){
 8     int t=0,f=1;char ch=getchar();
 9     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
10     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
11     return t*f;
12 }
13 int main(){
14     n=read();
15     int ans=1<<30;
16     for (int i=1;i<=n;i++)
17      l[i]=read();
18     for (int i=1;i<=n;i++)
19      c[i]=read();
20     for (int i=1;i<=n;i++){
21         int tot=0,t=l[i];
22         for (int j=2;j*j<=t;j++){
23             if (t%j==0){
24                 tot++;p[tot]=j;
25                 while (t%j==0) t/=j;
26             }
27         }
28         if (t!=1) p[++tot]=t;
29         for (int j=1;j<=n;j++)
30          if (j!=i){
31             val[j]=0;
32             for (int k=1;k<=tot;k++)
33              if (l[j]%p[k]==0)
34               val[j]|=1<<(k-1);
35          }
36         int sum;
37         val[i]=sum=(1<<tot)-1;
38         for (int j=1;j<=n;j++)
39          for (int k=0;k<=sum;k++)
40           f[j][k]=1<<30;
41         f[i][sum]=c[i];
42         for (int j=i;j<=n-1;j++)
43          for (int k=0;k<=sum;k++)
44           if (f[j][k]!=1<<30){
45             f[j+1][k]=std::min(f[j+1][k],f[j][k]);
46             f[j+1][k&val[j+1]]=std::min(f[j+1][k&val[j+1]],f[j][k]+c[j+1]);
47           }
48         if (f[n][0]!=1<<30){
49             ans=std::min(ans,f[n][0]);
50         }    
51     }
52     if (ans!=1<<30) printf("%d\n",ans);
53     else 
54     printf("-1\n");
55     return 0;
56 }

 

posted @ 2016-06-30 14:47  GFY  阅读(167)  评论(0编辑  收藏  举报