• 模拟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的超集),从而给状压那一块的复杂度开了个根号。

  • 相关阅读:
    佛山Uber优步司机奖励政策(2月1日~2月7日)
    长沙Uber优步司机奖励政策(2月1日~2月7日)
    广州Uber优步司机奖励政策(2月1日~2月7日)
    西安Uber优步司机奖励政策(2月1日~2月7日)
    武汉Uber优步司机奖励政策(2月1日~2月7日)
    Apicloud自定义模块
    Android Studio导出jar包
    android studio 、 as 如何导入eclipse项目
    安卓 使用Gradle生成正式签名apk文件
    如何用Android studio生成正式签名的APK文件
  • 原文地址:https://www.cnblogs.com/skyh/p/11566239.html
Copyright © 2020-2023  润新知