本文主要是介绍牛客第五场 E independent set 1 —— 状压 dp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:点我啊╭(╯^╰)╮
题目大意:
n n n 个点,求所有能组成的集的最大独立集的和
解题思路:
n ≤ 26 n≤26 n≤26,所以可以 状压 d p dp dp
a x a_x ax 表示 x x x 这个点连的边的状态
l b x lb_x lbx 表示 x x x 二进制中最低位为 1 1 1 的位置
__ b u i l t i n builtin builtin_ c t z ( x ) ctz(x) ctz(x) 表示 x x x 末尾有多少个 0 0 0
d p [ x ] dp[x] dp[x] 表示 x x x 这个集的最大独立集的 s i z e size size
然后随便删去一个点, x x x 的 d p dp dp 值即为删去后的答案与未删的答案 + 1 +1 +1 取 m a x max max
d p [ x ] = m a x ( d p [ x ⨁ l b ] , c h a r ( d p [ x dp[x] = max(dp[x \bigoplus lb], char(dp[x dp[x]=max(dp[x⨁lb],char(dp[x & ( a [ _ _ b u i l t i n _ c t z ( x ) ] ) ] + 1 ) ) (~a[\_\_builtin \_ctz(x)])] + 1)) ( a[__builtin_ctz(x)])]+1))
P S : PS: PS:题目卡内存。。用 4 4 4 字节的 i n t int int 会爆
需要用 1 1 1 字节的 c h a r char char ,最多只能存 255 > n 255 > n 255>n
核心:位元状压dp与独立集的应用
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
int n, m, a[26];
ll ans;
char dp[(1<<26) + 5];int lowbit(int x){return x & (-x);
}int main() {scanf("%d%d", &n, &m);while(m--){int u, v;scanf("%d%d", &u, &v);a[u] |= (1<<v); a[v] |= (1<<u); }for(int i=0; i<n; i++) a[i] |= (1<<i);for(int s=1; s<(1<<n); s++){int lb = lowbit(s);dp[s] = max(dp[s^lb], char(dp[s&(~a[__builtin_ctz(s)])] + 1));ans += int(dp[s]);}printf("%lld\n", ans);
}
这篇关于牛客第五场 E independent set 1 —— 状压 dp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!