zoukankan      html  css  js  c++  java
  • bzoj3275: Number

    Description

    有N个正整数,需要从中选出一些数,使这些数的和最大。
    若两个数a,b同时满足以下条件,则a,b不能同时被选
    1:存在正整数C,使a*a+b*b=c*c
    2:gcd(a,b)=1

    Input

    第一行一个正整数n,表示数的个数。
    第二行n个正整数a1,a2,?an。
     
     

    Output

    最大的和。
     

    Sample Input

    5
    3 4 5 6 7



    Sample Output

    22


    HINT

    n<=3000。

    Source

     
    题解:
    先将求最大值改为负的最小费用
    选了一个数x看成造成-x的费用,同时选了不能同时选的点对看成inf的费用
    然后发现K值是负的,那么这个图有没有二分图性质呢
    答案显然是有的(不然有这题干什么)
    若存在正整数a,b,c,满足a2+b2=c2,且a,b互质,那么a和b的奇偶性不同
    证明:正整数显然表示成4k,4k+1,4k+2,4k+3中的一种
    而 (4k)mod 4 = 0
    (4k+1)2 mod 4 = 1
    (4k+2)2 mod 4 = 0
    (4k+3)2 mod 4 = 1 
    显然 (amod 4)+(b2 mod 4)=(cmod 4) 
    1. c如果为 4k 或 4k+2,只有amod 4和bmod 4都是0才有可能满足上式,但这不满足a,b互质的要求(显然a和b此时都是偶数)
    2. c如果为 4k+1 或 4k+3,amod 4和bmod 4不能同为0或1,此时a,b的奇偶性不同
    所以只有可能在一对奇偶不同的数才由可能建边,所以这个图有二分图性质
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 3005
     7 #define maxm 6000000
     8 #define inf 1061109567
     9 using namespace std;
    10 char ch;
    11 bool ok;
    12 void read(int &x){
    13     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    15     if (ok) x=-x;
    16 }
    17 int n,a[maxn],sum;
    18 struct flow{
    19     int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm];
    20     int dis[maxn],head,tail,list[maxn];
    21     bool bo[maxn];
    22     void init(){s=0,t=n+1,tot=1,memset(now,0,sizeof(now));}
    23     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    24     void add(int a,int b,int c){put(a,b,c),put(b,a,0);}
    25     bool bfs(){
    26         memset(bo,0,sizeof(bo));
    27         head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1;
    28         while (head<tail){
    29             int u=list[++head];
    30             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    31                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,list[++tail]=v;
    32         }
    33         return bo[t];
    34     }
    35     int dfs(int u,int rest){
    36         if (u==t) return rest;
    37         int ans=0;
    38         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
    39             if (val[p]&&dis[v]==dis[u]+1){
    40                 int d=dfs(v,min(rest,val[p]));
    41                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
    42             }
    43         if (!ans) dis[u]=-1;
    44         return ans;
    45     }
    46     int dinic(){
    47         int ans=0;
    48         while (bfs()) ans+=dfs(s,inf);
    49         return ans;
    50     }
    51 }f;
    52 int gcd(int a,int b){return b?gcd(b,a%b):a;}
    53 int main(){
    54     read(n),f.init();
    55     for (int i=1;i<=n;i++){
    56         read(a[i]),sum+=a[i];
    57         if (a[i]&1) f.add(i,f.t,a[i]); else f.add(f.s,i,a[i]);
    58     }
    59     for (int i=1;i<=n;i++) if (!(a[i]&1)) for (int j=1;j<=n;j++) if (a[j]&1){
    60         int tmp=round(sqrt(a[i]*a[i]+a[j]*a[j]));
    61         if (gcd(a[i],a[j])==1&&tmp*tmp==a[i]*a[i]+a[j]*a[j]) f.add(i,j,inf);
    62     }
    63     printf("%d
    ",sum-f.dinic());
    64     return 0;
    65 }
  • 相关阅读:
    使用Session防止表单重复提交
    Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结
    Eclipse 设置文件的默认打开方式
    使用maven创建web项目
    solr配置中文分词器——(十二)
    solr后台界面介绍——(十一)
    solr4.10.3部署到tomcat——(十)
    Java与计算机常识
    solr简介——(九)
    Redis简介——(一)
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5146285.html
Copyright © 2011-2022 走看看