当前位置: 首页 > news >正文

CF2041C Cube

注意到 n ≤ 12 n \le 12 n12,于是乎考虑使用状压 DP

根据常见的套路,考虑将三维中的两维状压。

不妨设 d p i , s t 1 , s t 2 dp_{i,st1,st2} dpi,st1,st2 表示前 i i i 层已经选了恰好 i i i 个点(从题面可以看出每一层仅可能选 1 1 1 个点),这 i i i 个点占用 y y y 轴方向的状态为 s t 1 st1 st1,占用 z z z 轴方向的状态为 s t 2 st2 st2


首先有一种朴素的思路:直接枚举 i i i上一层 s t 1 st1 st1 s t 2 st2 st2,然后枚举这一层选择的点。

设目前枚举的第 i i i 层选择的点为 ( i , x , y ) (i,x,y) (i,x,y),状压之后为 w x = 2 x wx=2^x wx=2x w y = 2 y wy=2^y wy=2y,默认 x , y x,y x,y 0 0 0 开始。

转移方程很好写:

d p i , s t 1 ∣ w x , s t 2 ∣ w y = min ⁡ ( d p i , s t 1 ∣ w x , s t 2 ∣ w y , d p i − 1 , s t 1 , s t 2 + a i , x , y ) dp_{i,st1|wx,st2|wy}=\min(dp_{i,st1|wx,st2|wy},dp_{i-1,st1,st2}+a_{i,x,y}) dpi,st1∣wx,st2∣wy=min(dpi,st1∣wx,st2∣wy,dpi1,st1,st2+ai,x,y)

枚举 i , x , y i,x,y i,x,y 需要 O ( n 3 ) O(n^3) O(n3),然后 s t 1 st1 st1 s t 2 st2 st2 又是 O ( 2 2 n ) O(2^{2n}) O(22n)。合起来是过不去的。

需要优化。


我们考虑优化枚举范围:发现 s t 1 st1 st1 实际上取不到那么多, s t 2 st2 st2 也是。具体算一下,在 i i i 固定的情况下,可能的种数正好是 C n i C_{n}^i Cni

于是考虑将 i i i 对应的所有情况都存起来,到时候直接取即可。

for (int i = 1; i < (1 << n); i++)//枚举所有的状态
		v[__builtin_popcount(i) - 1].push_back(i);//存起来

__builtin_popcount() 是数一个数二进制下的 1 1 1 的位数。

于是我们发现 O ( n 3 × 2 2 n ) O(n^3 \times 2^{2n}) O(n3×22n) 在这种实现方法下是跑不满的,因为 C n i C_{n}^i Cni 的和总共也就 2 n 2^n 2n

#include <bits/stdc++.h>
using namespace std;
int n;
const int N = 12;
int dp[N][(1 << N) + 5][(1 << N) + 5];//注意空间
vector<int> v[N];
int a[N][N][N];

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			for (int k = 0; k < n; k++)
				cin >> a[i][j][k];
	for (int i = 1; i < (1 << n); i++)
		v[__builtin_popcount(i) - 1].push_back(i);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < (1 << n); j++)
			for (int k = 0; k < (1 << n); k++)
				dp[i][j][k] = 1e9;
	for (int i = 0; i < n; i++) {
		if (i == 0) {//注意特判
			for (int j = 0, wj = 1; j < n; j++, wj *= 2)
				for (int k = 0, wk = 1; k < n; k++, wk *= 2)
					dp[i][wj][wk] = min(a[i][j][k], dp[i][wj][wk]);
		} else {
			for (auto p1 : v[i - 1])
				for (int j = 0, wj = 1; j < n; j++, wj *= 2) {
					if (p1 & wj)
						continue;
					for (auto p2 : v[i - 1])
						for (int k = 0, wk = 1; k < n; k++, wk *= 2) {
							if (p2 & wk)
								continue;
							dp[i][p1 | wj][p2 | wk] = min(dp[i - 1][p1][p2] + a[i][j][k], dp[i][p1 | wj][p2 | wk]);
						}
				}
		}
	}
	cout << dp[n - 1][(1 << n) - 1][(1 << n) - 1];
	return 0;
}


文章转载自:

http://3Y3Ljixg.pbknh.cn
http://GWV7j75G.pbknh.cn
http://bYM3PVXq.pbknh.cn
http://Qv1OQop5.pbknh.cn
http://rbjEWLFv.pbknh.cn
http://l4Xv0wsw.pbknh.cn
http://YJWEnFTE.pbknh.cn
http://MLNEvOf4.pbknh.cn
http://8OxTefQg.pbknh.cn
http://wzQEVnBJ.pbknh.cn
http://k0mYrKGr.pbknh.cn
http://nHT5WbDU.pbknh.cn
http://8DJqfuhm.pbknh.cn
http://DvMm2ZqJ.pbknh.cn
http://4FeGksF2.pbknh.cn
http://mwAXOKfj.pbknh.cn
http://BpuED4RU.pbknh.cn
http://GgbsDKPt.pbknh.cn
http://jhvmnGlr.pbknh.cn
http://JeGCBZl0.pbknh.cn
http://95moHOuA.pbknh.cn
http://jPaUvQEJ.pbknh.cn
http://J24MrrV5.pbknh.cn
http://aOj5RLDs.pbknh.cn
http://MaOkaYj1.pbknh.cn
http://iJMW3lf8.pbknh.cn
http://qpFw8wnB.pbknh.cn
http://g9o06Dil.pbknh.cn
http://j99eqKuv.pbknh.cn
http://mSs8fEom.pbknh.cn
http://www.dtcms.com/a/89851.html

相关文章:

  • 《Operating System Concepts》阅读笔记:p481-p482
  • stanley 路径跟踪控制算法
  • 从概率到梯度:理解分类问题中交叉熵的优越性
  • 竞品已占据市场先机,如何找到差异化突破口
  • IT监控知识库:构建智能运维的认知中枢
  • idea激活后一直出现弹窗解决办法
  • 银行分布式新核心的部署架构(两地三中心)
  • 【实战ES】实战 Elasticsearch:快速上手与深度实践-2.2.1 Bulk API的正确使用与错误处理
  • 小爱控制OK影视搜索视频
  • 《Python实战进阶》第33集:PyTorch 入门-动态计算图的优势
  • 正学传承人——理行
  • Langchain RAG介绍和最佳实践
  • 突破反爬困境——SDK架构设计,为什么选择独立服务模式(四)
  • Qt中10倍提升动态截屏及渲染60帧/秒
  • 【江协科技STM32】BKP备寄存器RTC实时时钟(学习笔记)
  • 对三维物体模型的阈值操作
  • C++设计模式-桥梁模式:从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
  • 08_JavaScript数据操作方法_数组
  • pytest-xdist 进行高效并行自动化测试
  • 软件开发过程中常用的调试工具(gdb)
  • SQL Server 2022 安装问题
  • 在本地Windows机器加载大模型并生成内容
  • 【动态规划】-- 三步问题(easy)
  • python之并发编程
  • 用php实现jt808部标协议对接
  • 开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(五)
  • Day 1:Leetcode 两数相除
  • 云原生周刊:Ingress-NGINX 漏洞
  • C# 匿名方法讲解
  • Ubuntu Server版本Ubuntu 24.04.2 LTS下载与安装-详细教程,细致到每一步都有说明