zoukankan      html  css  js  c++  java
  • [状压DP]luogu P6622 [省选联考 2020 A/B 卷] 信号传递

    题面

    https://www.luogu.com.cn/problem/P6622

    分析

    枚举每个信号塔的位置显然不行,考虑设置 DP 状态

    f[S] 表示选择了集合为 S 的塔,排在前 |S| 个位置

    方程则为 $f[S|i]=f[S]+h[S,i]$ $h[S,i]$ 表示 S 中与 i 有连边的贡献

    $h[S,i]$ 怎么求呢?据题意有

    $w_{i,j}=j-i (i<j)$

    $w_{i,j}=ki+kj (i>j)$

    发现可以对于每个位置来计算贡献,有一条向后的出边则 -1 ,向前的出边则 +k ,从后来的入边则 +k ,从前来的入边则 +1

    设 $c_{i,j}$ 为 i 到 j 的边数,则有 $h[S,i]=(|S|+1) imes(sum_{jin S}(kc_{i,j}+c_{j,i}) + sum_{j otin S|i}(kc_{j,i}+c_{i,j}))$

    这样时间复杂度是 $O(m^22^m)$ 的,如果从低位往高位枚举 S 并同时转移 h[S,i] ,则可以压到 $O(m2^m)$

    但是空间复杂度仍然不足以AC,瓶颈在于 h[S,i] 

    发现如果从小往大枚举,那么最近枚举的一个位数为 i 的状态 S 枚举到下一个位数为 i 的状态 S' 之前一定会枚举到一个位数为 i+1 的状态 S'' ,而 S'' 显然为 S+lowbit(S)

    所以可以直接改为 h[|S|,i] ,每次转移的时候从 h[|S|-1,i] 加上对应贡献即可

    代码

    #include <iostream>
    #include <cstdio>
    #define lowbit(x) (x&-x)
    using namespace std;
    const int Inf=2147483647;
    const int N=1e5+1;
    const int M=23;
    int n,m,k;
    int g[M][M],f[1<<M],h[M][M],cnt[1<<M],lg[1<<M];
    
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        int u;scanf("%d",&u);
        for (int i=1,v;i<n;i++) scanf("%d",&v),g[u-1][v-1]++,u=v;
        for (int i=0;i<m;i++)
            for (int j=0;j<m;j++)
                if (i!=j) h[0][i]+=k*g[j][i]-g[i][j];
        n=1<<m;lg[0]=-1;for (int i=1;i<n;i++) lg[i]=lg[i>>1]+1,cnt[i]=cnt[i-lowbit(i)]+1,f[i]=Inf;
        for (int i=0;i<n-1;i++) {
            if (i) for (int j=0;j<m;j++) h[cnt[i]][j]=h[cnt[i]-1][j]-k*g[lg[lowbit(i)]][j]+k*g[j][lg[lowbit(i)]]+g[j][lg[lowbit(i)]]+g[lg[lowbit(i)]][j];
            for (int j=(n-1)^i;lowbit(j);j-=lowbit(j)) f[i|lowbit(j)]=min(f[i|lowbit(j)],f[i]+h[cnt[i]][lg[lowbit(j)]]*(cnt[i]+1));
        }
        printf("%d
    ",f[n-1]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    uwsgi+nginx+django
    uwsgi怎么启动停止
    centos7 命令
    django 配置静态文件
    centos7 安装node
    python 字符串拼接
    Python 编码
    python 文件夹递归
    ArcGIS二次开发的几种方式
    集合的操作
  • 原文地址:https://www.cnblogs.com/mastervan/p/14586153.html
Copyright © 2011-2022 走看看