简单解释一下:因为 x 新加入了 S 集合,加上 x 在集合 S 中的贡献,再刨去之前算的 x 不在集合 S 中的贡献
这样时间复杂度降为 O(m2m) ,在时间方面可以通过此题。
优化空间
A:m≤23 ,你 cost 数组开多大?
B:emm... ,1024∗1024223×23×2=736 ,空间限制 512MB,……
A:有冗余状态🐴?
B:em……,对于 x∈S,cost[x][S] 是冗余的,哦!那可以直接枚举一个二进制长度为 m−1 的长度,表示不算 x 时选的结点,……哦可能这么说你不太懂,那直接看代码吧
1 2 3 4 5 6 7 8 9 10 11 12
for (int i = 0; i < m; ++i) {//枚举不算的那个点 for (int j = 0; j < m; ++j) if (i != j) cost[i][0] += k * E[j][i] - E[i][j];//初始化 for (int S = 1; S < 1 << (m - 1); ++S) { int x = lg[(S & -S)]; if (x >= i) ++x; //因为我刨除了i,所以要把i那一位腾出来 cost[i][S] = (cost[i][S ^ (S & -S)] + E[i][x] * (1 + k) + E[x][i] * (1 - k)); } }