寒假集训·子集枚举2

寒假集训·状压DP子集枚举2

P3052的加强版

与原版不同,这里的数据范围从最大为 181818 变为了 222222 ,这就意味着我们只能使用 2n∗n2^n*n2n∗n 的时间复杂度,那我们就必须把dp数组变成一维。

dp[s]dp[s]dp[s] 就表示在 sss 状态下,所需的最小电梯数;

因为我们还要看能不能再装一头牛,所以我们还需要存最后一个电梯的重量。

cnt[s]cnt[s]cnt[s] 就表示在 sss 状态下,最后一个电梯的已用最小空间。

还有一个需要注意的点

dp[0]=1;dp[0]=1;dp[0]=1;

因为这里 cnt[0]=0cnt[0]=0cnt[0]=0,意思就是最后一个(第一个)电梯装了 000 磅,那也应该写用了1个电梯。

代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n, m;
int c[25];
int dp[(1 << 22) + 5];
int cnt[(1 << 22) + 5];
int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> c[i];
	}
	memset(dp, 0x3f, sizeof dp);
	memset(cnt, 0x3f, sizeof cnt);
	dp[0] = 1;
	cnt[0] = 0;
	for (int s = 0; s < (1 << n); s++) {
		for (int i = 0; i < n; i++) {
			if (!(s & (1 << i))) {
				if (cnt[s] + c[i] <= m) {
					dp[s + (1 << i)] = min(dp[s + (1 << i)], dp[s]);
					cnt[s + (1 << i)] = min(cnt[s + (1 << i)], cnt[s] + c[i]);
				} else {
					dp[s + (1 << i)] = min(dp[s + (1 << i)], dp[s] + 1);
					cnt[s + (1 << i)] = min(cnt[s + (1 << i)], c[i]);
				}
			}
		}
	}
	for (int s = 0; s < (1 << n); s++) {
//		cout << "dp[" << s << "]: " << dp[s] << "  cnt[" << s << "]: " << cnt[s] << '\n';
	}
//	cout << '\n';
	cout << dp[(1 << n) - 1];
	return 0;
}

P5911 [POI 2004] PRZ

变式题,在上一道题的基础上计算答案的方法变成了取最慢的人,其他大概逻辑没有很大变化。

AT_dp_u Grouping

可以经过计算得出:此时时间复杂度为 3n3^n3n ,卡着过,所以枚举子集里不能有其他东西,但是我们又要获取状态 sss 的相性和,怎么办?预处理。

cpp 复制代码
for (int s = 0; s < (1 << n); s++) {  //状态
		for (int i = 0; i < n; i++) {  //枚举兔子i
			for (int j = i + 1; j < n; j++) {  //枚举兔子j
				if ((s & (1 << i)) && (s & (1 << j))) {  //都选了
					pre[s] += dis[i][j];
				}
			}
		}
	}

转移方程:
dp[s] = max(dp[s], dp[s ^ t] + pre[t]);

代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int dis[25][25];
ll pre[(1 << 16) + 5];
ll dp[(1 << 16) + 5];
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> dis[i][j];
		}
	}
	for (int s = 0; s < (1 << n); s++) {
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				if ((s & (1 << i)) && (s & (1 << j))) {
					pre[s] += dis[i][j];
				}
			}
		}
	}
//	for (int s = 0; s < (1 << n); s++) {
//		cout << pre[s] << ' ';
//	}
//	cout << '\n';
	dp[0] = 0;
	for (int s = 0; s < (1 << n); s++) {
		for (int t = s; t; t = (t - 1)&s) {
			dp[s] = max(dp[s], dp[s ^ t] + pre[t]);
		}
	}
//	for (int s = 0; s < (1 << n); s++) {
//		cout << dp[s] << ' ';
//	}
//	cout << '\n';
	cout << dp[(1 << n) - 1];
	return 0;
}

P2167 [SDOI2009] Bill的挑战

定义 dp[i][mask]dp[i][mask]dp[i][mask] 表示构造到第 iii 位时,匹配的字符串集合为 maskmaskmask 的方案数;

预处理数组:f[i][ch]f[i][ch]f[i][ch] 表示第 iii 位填入字符 chchch 时,能匹配的字符串集合(二进制 maskmaskmask ),计算规则为:遍历所有字符串,若该字符串第 iii 位是 ??? 或等于 chchch,则对应位为 111;

状态转移:
dp[i+1][mask & f[i][ch]] += dp[i][mask]

当前位选字符 chchch 时,新的匹配状态为原状态与 f[i][ch]f[i][ch]f[i][ch] 的交集,方案数累加

初始化:dp[0][(1<<n)-1] = 1(第 000位未构造时,所有字符串都处于"匹配"状态,方案数为 111)。

P3694 邦邦的大合唱站队

前缀和数组 pre[j][i]pre[j][i]pre[j][i](0-based):表示原队列前 i+1i+1i+1 个位置(0~i)中,第 jjj 支乐队(0-based)的偶像数量,用于 O(1)O(1)O(1) 查询任意区间内某乐队的人数;

计数数组 f[j]f[j]f[j]:统计第 jjj 支乐队的总人数;

状态和数组 sum[mask]sum[mask]sum[mask]:表示 maskmaskmask 对应的乐队集合的总人数( maskmaskmask 为二进制状态,第 jjj 位为 111 表示选了第j支乐队)。

状态定义:dp[mask]dp[mask]dp[mask] 表示选 maskmaskmask 对应的乐队集合时,使这些乐队连续排列的最少出列人数;

初始化:dp[0] = 0(选 000 支乐队时出列人数为 000),其余初始化为极大值;

状态转移:遍历每个状态 maskmaskmask,尝试加入未选的乐队j,计算该乐队占据区间 [sum[mask][sum[mask][sum[mask], sum[mask]+f[j]-1]的出列成本(成本=区间长度−区间内原有的j乐队人数成本=区间长度-区间内原有的j乐队人数成本=区间长度−区间内原有的j乐队人数),更新dp[mask | (1<<j)] = min(原值, dp[mask]+成本)

相关推荐
CoovallyAIHub3 小时前
Moonshine:比 Whisper 快 100 倍的端侧语音识别神器,Star 6.6K!
深度学习·算法·计算机视觉
CoovallyAIHub4 小时前
速度暴涨10倍、成本暴降6倍!Mercury 2用扩散取代自回归,重新定义LLM推理速度
深度学习·算法·计算机视觉
CoovallyAIHub4 小时前
实时视觉AI智能体框架来了!Vision Agents 狂揽7K Star,延迟低至30ms,YOLO+Gemini实时联动!
算法·架构·github
CoovallyAIHub5 小时前
开源:YOLO最强对手?D-FINE目标检测与实例分割框架深度解析
人工智能·算法·github
CoovallyAIHub5 小时前
OpenClaw:从“19万星标”到“行业封杀”,这只“赛博龙虾”究竟触动了谁的神经?
算法·架构·github
刀法如飞5 小时前
程序员必须知道的核心算法思想
算法·编程开发·算法思想
徐小夕7 小时前
pxcharts Ultra V2.3更新:多维表一键导出 PDF,渲染兼容性拉满!
vue.js·算法·github
CoovallyAIHub8 小时前
OpenClaw一脚踩碎传统CV?机器终于不再只是看世界
深度学习·算法·计算机视觉
CoovallyAIHub8 小时前
仅凭单目相机实现3D锥桶定位?UNet-RKNet破解自动驾驶锥桶检测难题
深度学习·算法·计算机视觉
zone77398 小时前
002:RAG 入门-LangChain 读取文本
后端·算法·面试