算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目。。

对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp.

观察最后答案是一个连通块 从而可以发现这个连通块必然存在一个深度最浅的点且唯一 所以随便找一个点做根然后对自己子树内寻找答案就可以是正确的。

考虑另外的30%的数据k<=3 可是颜色数最多可以有n个 不知道哪个是最终答案。

一次状压dp的复杂度:\(2^{2k}\cdot n\)

容易得到可以暴力枚举一下 然后要做 \(C(n,3)\) 这样会TLE。

此时可以考虑一种随机化:每次随机三个颜色是谁 这样一直跑...

显然这个和上面那个差不多 也是一个低效率的随机 这里要用到一个非常好用的思路 曾经在[GXOI/GZOI2019]旅行者 这道题中有类似的体现。

后者是 发现每次跑最短路可以跑多源对多源的且一些不优的点对对答案无影响 才可以进一步的使用不断的分组来得到答案。

而这个 可以考虑另外一种比较高效的随机 不需要每次都求出到底是哪几个点是答案 而我们只需要让其在答案中得到体现。

做法是 由于只有k个位置 给每个颜色rand一个位置然后直接求 这样做可以发现如果不是最优解 那么显然答案会更小 对答案没影响。

观察一下这样随机的效率\(\frac{k!}{k^k}\) 每做一次是0.03的概率 那么做多次概率就>1了 在期望的角度是很容易得到正确答案的。

这里我加了卡时 强制跑0.8s再退出 这样正确性会更高.

code
  1. //#include<bits/stdc++.h>
  2. #include<iostream>
  3. #include<iomanip>
  4. #include<cstdio>
  5. #include<ctime>
  6. #include<cstdlib>
  7. #include<cctype>
  8. #include<cstring>
  9. #include<cmath>
  10. #include<string>
  11. #include<utility>
  12. #include<queue>
  13. #include<vector>
  14. #include<algorithm>
  15. #include<deque>
  16. #include<stack>
  17. #include<list>
  18. #include<bitset>
  19. #include<set>
  20. #include<map>
  21. #define INF 1000000000000000000ll
  22. #define rep(p,n,i) for(int i=p;i<=n;++i)
  23. #define fep(n,p,i) for(int i=n;i>=p;--i)
  24. #define vep(p,n,i) for(int i=p;i<n;++i)
  25. #define db double
  26. #define get(x) x=read()
  27. #define put(x) printf("%d\n",x)
  28. #define pb push_back
  29. #define ll long long
  30. #define db double
  31. #define putl(x) printf("%lld\n",x)
  32. using namespace std;
  33. char *fs,*ft,buf[1<<15];
  34. inline char getc()
  35. {
  36. return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
  37. }
  38. inline int read()
  39. {
  40. int x=0,f=1;char ch=getc();
  41. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
  42. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
  43. return x*f;
  44. }
  45. const int MAXN=10010,N=5;
  46. int n,k,len,ans,maxx;
  47. int a[MAXN],b[MAXN],c[MAXN],fa[MAXN];
  48. int f[MAXN][1<<N];
  49. int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
  50. inline void add(int x,int y)
  51. {
  52. ver[++len]=y;nex[len]=lin[x];lin[x]=len;
  53. ver[++len]=x;nex[len]=lin[y];lin[y]=len;
  54. }
  55. inline void dp(int x,int v)
  56. {
  57. fa[x]=v;
  58. for(int i=lin[x];i;i=nex[i])
  59. {
  60. int tn=ver[i];
  61. if(tn==v)continue;
  62. dp(tn,x);
  63. }
  64. }
  65. inline void dfs(int x)
  66. {
  67. f[x][1<<c[x]-1]=1;
  68. for(int i=lin[x];i;i=nex[i])
  69. {
  70. int tn=ver[i];
  71. if(tn!=fa[x])
  72. {
  73. dfs(tn);
  74. fep(maxx,1,w1)fep(maxx,1,w2)f[x][w1|w2]=min(f[x][w1|w2],f[x][w1]+f[tn][w2]);
  75. }
  76. }
  77. ans=min(ans,f[x][maxx]);
  78. }
  79. int main()
  80. {
  81. freopen("hao.in","r",stdin);
  82. freopen("hao.out","w",stdout);
  83. double st=clock();
  84. get(n);get(k);int mx=0;
  85. rep(1,n,i)get(a[i]),mx=max(mx,a[i]);
  86. rep(2,n,i)add(read(),read());
  87. dp(1,0);maxx=1<<k;--maxx;
  88. srand(time(0));ans=n;
  89. double ed=clock();
  90. while(ed-st<=880)
  91. {
  92. memset(f,0x3f,sizeof(f));
  93. rep(1,mx,j)b[j]=rand()%k+1;
  94. rep(1,n,j)c[j]=b[a[j]];
  95. dfs(1);
  96. ed=clock();
  97. }
  98. put(ans);return 0;
  99. }

6.28 NOI模拟赛 好题 状压dp 随机化的更多相关文章

  1. BZOJ 3812 主旋律 (状压DP+容斥) + NOIP模拟赛 巨神兵(obelisk)(状压DP)

    这道题跟另一道题很像,先看看那道题吧 巨神兵(obelisk) 题面 欧贝利斯克的巨神兵很喜欢有向图,有一天他找到了一张nnn个点mmm条边的有向图.欧贝利斯克认为一个没有环的有向图是优美的,请问这张 ...

  2. 2018.10.05 NOIP模拟 上升序列(状压dp)

    传送门 状压dp好题. 首先需要回忆O(nlogn)O(nlog n)O(nlogn)求lislislis的方法,我们会维护一个单调递增的ddd数组. 可以设计状态f(s1,s2)f(s1,s2)f( ...

  3. 2018.10.01 NOIP模拟 偷书(状压dp)

    传送门 状压dp经典题. 令f[i][j]f[i][j]f[i][j]表示到第i个,第i−k+1i-k+1i−k+1~iii个物品的状态是j时的最大总和. 然后简单维护一下转移就行了. 由于想皮一下果 ...

  4. 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)

    [描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...

  5. [欢乐赛]班服 状压DP

    班服 (shirt.pas/.c/.cpp) 时间限制:1s:内存限制 128MB 题目描述: 要开运动会了,神犇学校的n个班级要选班服,班服共有100种样式,编号1~100.现在每个班都挑出了一些样 ...

  6. 【思维题 状压dp】APC001F - XOR Tree

    可能算是道中规中矩的套路题吧…… Time limit : 2sec / Memory limit : 256MB Problem Statement You are given a tree wit ...

  7. P3694 邦邦的大合唱站队/签到题(状压dp)

    P3694 邦邦的大合唱站队/签到题 题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶 ...

  8. [CSP-S模拟测试]:装饰(状压DP)

    题目传送门(内部题114) 输入格式 第一行一个正整数$n$. 接下来一行$n-1$个正整数,第$i$个数为$f_{i+1}$. 接下来一行$n$个数,若第$i$个数为$0$则表示林先森希望$i$号点 ...

  9. 2018.09.28 hdu5434 Peace small elephant(状压dp+矩阵快速幂)

    传送门 看到n的范围的时候吓了一跳,然后发现可以矩阵快速幂优化. 我们用类似于状压dp的方法构造(1(1(1<<m)∗(1m)*(1m)∗(1<<m)m)m)大小的矩阵. 然后 ...

随机推荐

  1. scrapy框架携带cookie访问淘宝购物车

    我们知道,有的网页必须要登录才能访问其内容.scrapy登录的实现一般就三种方式. 1.在第一次请求中直接携带用户名和密码. 2.必须要访问一次目标地址,服务器返回一些参数,例如验证码,一些特定的加密 ...

  2. CSS让一个图片显示在另一个图片上面

    思路,在两个图片的父元素上设置  position:relative  , 然后给小图片设置 position:absolute ,位置通过top,bottom,left,right来修改,然后用  ...

  3. Linux多任务编程之三:exec函数族及其基础实验(转)

    来源:CSDN  作者:王文松  转自:Linux公社 exec函数族 函数族说明 fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?e ...

  4. Configurate root account

    After having installed Ubuntu OS, you should update config file for root account. The commands are l ...

  5. C++中类继承public,protected和private关键字作用详解及派生类的访问权限

    注意:本文有时候会用Visual Studio Code里插件的自动补全功能来展示访问权限的范围(当且仅当自动补全范围等价于对象访问权限范围的时候),但是不代表只要是出现在自动补全范围内的可调用对象/ ...

  6. Python 爬取异步加载的数据

    在我们的工作中,可能会遇到这样的情况:我们需要爬取的数据是通过ajax异步加载的,这样的话通过requests得到的只是一个静态页面,而我们需要的是ajax动态加载的数据! 那我们应该怎么办呢??? ...

  7. 【高性能Mysql 】读书笔记(一)

    第1章 Mysql架构与历史 MYSQL最重要.最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理( Query Processing)及其他系统任务( Server Task)和数据的存储 ...

  8. IDEA JRebel热部署( IDEA版本是2020.1.2)

    1.安装JRebel插件 在IDEA->Settings->plugins先安装JRebel插件: 2.下载工具 安装好JRebel后,找到lanyus大神文章中写的git地址:http: ...

  9. SpringBoot2.x入门教程:引入jdbc模块与JdbcTemplate简单使用

    这是公众号<Throwable文摘>发布的第23篇原创文章,收录于专辑<SpringBoot2.x入门>. 前提 这篇文章是<SpringBoot2.x入门>专辑的 ...

  10. echarts 实战 : 怎么写出和自动生成的一样的 tooltip ?

    找到答案很麻烦,但答案本身很简单. 假设 需要给 echarts 的数据是 option. option.tooltip.formatter = (params) => { return `&l ...