AtCoder Beginner Contest 318 - D(状压 dp)

D - General Weighted Max Matching

题意
给定无向图,边有边权。让你选择一组边,满足任意两边不相交且总边权和最大。
顶点数 $\le 16 $

思路
状压 DP 求解该问题
状态:利用 n 位二进制表示每个顶点是否已经被选择,0 表示该顶点未选,1 表示当前顶点已选
转移:每一个二进制数表示的状态可以通过加入新的边进行转移

边是否选择与点是否选择等价,且我们不关心之前怎么选的边,只关心新加边如何转移,以及之前加的边对于答案的影响

代码

void solve(){
	int n;
	cin >> n;
	vector d(n, vector<int>(n, 0));
	for(int i = 0; i < n; ++ i){
		for(int j = i + 1; j < n; ++ j){
			cin >> d[i][j];
		}
	}
	vector<ll> dp(1 << n, 0);
	ll ans = 0;
	for(int i = 0; i < (1 << n); ++ i){
		for(int j = 0; j < n; ++ j){
			if(!(i >> j & 1)){
				for(int k = j + 1; k < n; ++ k){
					if(!(i >> k & 1)){
						int t = i | (1 << j) | (1 << k);
						dp[t] = max(dp[t], dp[i] + d[j][k]);
					}
				}
			}
		}
		ans = max(ans, dp[i]);
	}
	cout << ans << '\n';
	return ;
}
posted on 2023-09-07 20:29  Qiansui  阅读(30)  评论(0编辑  收藏  举报