zoukankan      html  css  js  c++  java
  • 模拟48 题解

    A. String Master

    $O(n^3)$随便做。

    B. Tourist Attractions

    因为数据范围$n^2$没有任何问题。

    考虑设$dp(i,j,k)$表示节点i从节点j来,并再走k步的方案数。

    显然$dp(i,j,1)=du(i)-1$,除了返回j,别的方案都是可行的。

    设$link(i,j)$表示i,j是否联通的0/1变量。

    $dp(i,j,2)=sum limits_{k,link(i,k)}dp(k,i)-link(k,j)$,当k可以走回j的时候,可能造成重复计数,故减去。

    $dp(i,3)=sum limits_{k,link(i,k)}dp(k,i)$

    $ans=sum limits_{i=1}^{n}dp(i,3)$

    瓶颈在于如何求$dp(i,j,2)$,暴力求是$O(n^3)$的。

    不妨将式子中加和减的两项拆开,那么发现bitset维护一下i走到k再走到j的方案数就可以了。

    C. Walk

    70分暴力,每个值只在bfs第一次出现时,更新一遍它的所有子集。

    枚举子集的复杂度是$O(3^k)$的。(k为val二进制下最大的位数)

    问题在于如何将$3^k$的边转化为$2^k$级别。

    考虑由每个权值向1的个数减少1的权值建边权为0的边,那么边的个数为$k*2^k$级别。

    由点向权值建边权为0的边,权值向对应的点建权值为1的边。

    因为权值只有0/1两种形式,双端队列bfs。

    另外,如果点向权值建边权为1的边,权值向点建权值为0的边。

    这样进行bfs是错误的,原因是可能导致点被提前更新更大的答案。

    另外记录一道与本题稍有一点关系的特殊的题目(LadyLex学长的课件):

    有$2^{20}$个元素,每次使某元素对给定值取$max$,求某个数代表的二进制的子集中元素的最大值。

    有这样的状态定义:$F[i][j]$代表“状态s的前一半数位为i的子集,后一半数位为j”的方案数/最小值等信息。

    这样在更新和查找的时候,我们都只需要枚举一半的数位(查找枚举j的子集,更新枚举i的超集),从而给状压那一块的复杂度开了个根号。

  • 相关阅读:
    Ubuntu麒麟社区的行为准则(Code of Conduct)
    Delphi 用WinInet 单元实现 POST提交数据
    linux下IPTABLES配置详解
    modelsim 安装后运行,出现fatal License Error
    设计Web应用程序时要注意可伸缩性
    计算机端口详细介绍(整理版)
    Eclipse程序员要掌握的常用快捷键
    程序员怎么才能提高代码编写速度?
    做有中国特色的程序员
    网站建设中关于并发连接数的解释
  • 原文地址:https://www.cnblogs.com/skyh/p/11566239.html
Copyright © 2011-2022 走看看