• a_lc_连通两组点的最小成本(状压+枚举两种连法)


    任意两点间的连接成本 cost 由大小为 size1 x size2 矩阵给出,其中 cost[i][j] 是第一组中的点 i 和第二组中的点 j 的连接成本
    第一组中的每个点必须至少与第二组中的一个点连接,且第二组中的每个点必须至少与第一组中的一个点连接。
    1 <= size1, size2 <= 12

    我当时的做法的case通过数量是45/83,可能是没有考虑完或者边界问题(没时间改),参考别人的状态压缩dp,对于第一组的每个点i:

    • 第一种连法:直接连接第二组的每个点
    • 第二种连法:连接第二组没有连接到的点

    题目还是很良心的,不用自己通过对比size1, size2来确定哪一维用作状态压缩

    const int inf=0x3f3f3f3f;
    class Solution {
    public:
        int connectTwoGroups(vector<vector<int>>& cost) {
            int n=cost.size(), m=cost[0].size(), tot=1<<m, f[n+1][tot];
            memset(f, inf, sizeof f); f[0][0]=0;
    
            for (int i=1; i<=n; i++)
            for (int st=0; st<tot; st++) {
                //连接第二组中任意一个点
                if (f[i-1][st]!=inf) {
                    for (int j=0; j<m; j++) {
                        int nx=st|(1<<j);
                        f[i][nx]=min(f[i][nx], f[i-1][st]+cost[i-1][j]);
                    }
                }
                int other_st=(tot-1)^st;    //第二组点中没有被连接到的所有点的状态集合
                for (int subset=other_st; subset; subset=other_st&(subset-1)) { //去掉other_set的最低位的1
                    int sum=0;
                    for (int j=0; j<m; j++) if (subset&(1<<j)) {
                        sum+=cost[i-1][j];
                    }
                    int nx=st|subset;
                    f[i][nx]=min(f[i][nx], f[i-1][st]+sum);   //这里一开始我写成了 f[i][subset]=...,这是错的,下一个状态没累加上初始状态
                }
            }
            return f[n][tot-1];
        }
    };
    

    复杂度分析

    • Time(O(nm2^m))
    • Space(O())
  • 相关阅读:
    python-列表基本方法
    成员/身份运算
    python-字符串常用方法
    python基础知识1
    jmeter_性能测试及报告分析
    Day3_linux_工作目录切换命令
    Day2_linux_查看系统状态
    Day1_liunx_常用系统工作命令
    互联网是有记忆的
    第3章 Python基础
  • 原文地址:https://www.cnblogs.com/wdt1/p/13703715.html
Copyright © 2020-2023  润新知