zoukankan      html  css  js  c++  java
  • 1524 可除图的最大团

    Problem

    对于一般的图,最大团问题是一个NP-难的问题。然而,对于一些特殊的图,最大团问题可以有比较有效的解决方案。

    关于最大团问题的概念,请百度之。^_^

    在一个正整数集合A上定义可除图。 A = {a1, a2, ..., an} ,图上的顶点就是集合A中的数字。两个数字 ai 和 aj (i ≠ j) 之间有一条边的条件是 ai 能够被 aj 整除,或者 aj 能够被 ai 整除.

    现在给定一个正整数集A,请找出这个集合所确定的可除图的最大团。

    样例解释:在这个例子中,最大团是3,可以选择 {3,6,18}。

    Solution

    很容易想到,从小到大构建一张有向图,一个数的因子向这个数连边,对于任意一个数a[i],要计算1e6/a[i]次,连边复杂度1e6×(1/1+1/2+1/3+...+1/1e6),是nlogn,然后拓扑排序做dp,结果就会发现,这样做过不了,是被卡常了。

    然后可以用dp[i]表示对于数字i,最大团数量是多少,同样的循环就能过了。。。

    Code

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const int mod=1000000007;
    int n,m;
    int a[1000020],dp[1000020],f[1000020];
    int ans;
    inline int rd(){
    	int x=0,f=1;
    	char ch;
    	while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    
    int main(){
    	n=rd();
    	for(int i=1;i<=n;i++){
    		a[i]=rd();
    		f[a[i]]=1;
    	}
    	sort(a+1,a+1+n);
    	for(int i=1;i<=n;i++){
    		if(dp[a[i]]==0) dp[a[i]]=1;
    		for(int j=a[i]*2;j<=a[n];j+=a[i]){
    			if(f[j]){
    				dp[j]=max(dp[j],dp[a[i]]+1);
    				//if(i==6) printf("%d %d
    ",j,dp[j]);
    			}
    		}
    		ans=max(ans,dp[a[i]]);
    		//printf("%d
    ",dp[a[i]]);
    	}
    	
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    微信小程序之文件(图片)使用MD5加密(二)
    微信小程序之文件(图片)使用MD5加密(一)
    02-Django简介
    01-Web框架的原理
    15-pymysql模块的使用
    06-数据类型
    05-表的操作
    04-库的操作
    03-初始mysql语句
    02-MySql安装和基本管理
  • 原文地址:https://www.cnblogs.com/sz-wcc/p/12831080.html
Copyright © 2011-2022 走看看