• 【洛谷P4212】外太空旅行【随机】【贪心】


    题目大意:

    题目链接:https://www.luogu.org/problemnew/show/P4212
    给出nn个人的关系,两个人不是朋友就是敌人。选择其中的kk个人,使得这kk个人都是朋友关系。求kk的最大值。


    思路:

    好的下面为大家带来一道状压DP50分DFS70分随机+贪心AC的题目(逃
    n50n\leq50,状压和DFS都得跑T。
    正解如下:

    1. 首先,你打了一个DFS想骗骗分,还拿了70分。
    2. 然后,你想到DFS都能拿70,就信心满满地去打了一个DP,结果只拿了50
    3. 于是你在DFS上乱加优化,成功优化到了90,但是最后一个点死活就是卡不过。
    4. 于是,无奈和愤怒交加的你点开了标签。。。
    5. 然后你就想到。。。在这里插入图片描述

    正解:

    正解是随机+贪心。
    可以随机一个序列,表示选人进入集合的序列。
    然后就按照枚举的序列开始贪心。如果这个人能进入集合(与集合里的所有人都是朋友关系),那么就将他进入集合,否则不进。
    然后就可以得出在这个序列的情况下的进入集合的人数。那么多次随机数列,并将每次的答案都进行比较,最后输出这几个答案的最优值即可。
    由于可以随机5000050000(甚至更多)次,所以答案基本就出来了。偶尔WA了就将随机次数开大即可。


    代码:

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int N=50000; 
    int n,a[61],x,y,ans,sum;
    bool f[61][61],p[61];
    
    int main()
    {
    	scanf("%d",&n);
    	while (scanf("%d%d",&x,&y)==2)
    	{
    		f[x][y]=true;
    		f[y][x]=true;
    	}
    	srand((unsigned long long)new char);  //随机种子
    	for (int k=1;k<=N;k++)
    	{
    		memset(p,0,sizeof(p));
    		for (int i=1;i<=n;i++)  //随机一个数列
    		{
    			while ((x=rand()%n+1)&&(p[x])) ;
    			a[i]=x;
    			p[x]=true;
    		}
    		memset(p,0,sizeof(p));
    		sum=0;
    		for (int i=1;i<=n;i++)
    		{
    			if (!p[a[i]])  //可以进入集合
    			{
    				sum++;
    				for (int j=1;j<=n;j++)
    				 if (!f[a[i]][j]) p[j]=true;  //将他的敌人标记
    			}
    		}
    		ans=max(ans,sum);
    	}
    	printf("%d\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    Newtonsoft.Json序列化 对时间格式化处理
    CSS常用提示浮出层的写法
    避免常见的6种HTML5错误用法
    varchar(Max) 对应SqlParameter 数据类型长度改为1
    IIS指定域名不能调试解决办法
    如何弹出固定大小及内容的网页窗口
    CSS图片圆角框的灵活处理
    精通CSS:高级Web标准解决方案(中文电子书下载)
    AjaxControlToolKit(整理)三.......(35个控件)简单介绍
    CSS通用开发库
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998576.html
Copyright © 2020-2023  润新知