【题解】洛谷 P2476 [SCOI2008] 着色方案 [记搜]

P2476 SCOI2008 着色方案 - 洛谷 (luogu.com.cn)(支持升蓝)

相当难的一道题。。想了半小时毫无头绪。

由于本人特别喜欢品时间复杂度做题,一遇到这种记搜题就惨败。


如果 k 再小一点,那我会毫不犹豫的记搜。

但现在符合记搜要求大小的只有 ,考虑从 上下手。

又发现颜色并不重要 ,重要的只有上一次涂的什么颜色,这一次不要重复了。

考虑将所有颜色不分品种,只根据 的大小分成 5 种,设计个状态:

cpp 复制代码
dp[a][b][c][d][e][last]
// 表示某颜色只能涂 1 下的有 a 个,能涂 2 下的颜色 b 个,...,以此类推
// 上一次的涂的颜色是 last , 如 last = 4 表示上一次用的是能涂 4 下的颜色中的某一个

计算一下状态数:,实际还要少得多,可以过。

详见代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL P = 1e9 + 7;
const int N = 17;

LL dp[N][N][N][N][N][6], inf;

LL dfs(int a, int b, int c, int d, int e, int last) {
	if (dp[a][b][c][d][e][last] != inf) {
		return dp[a][b][c][d][e][last];
	}
	if (a + b + c + d + e == 0) {
		return 1;
	}
	
	LL res = 0;
	if (a) {
		res = (res + (a - (last == 2)) * dfs(a - 1, b, c, d, e, 1)) % P;
		// 乘法原理,从所有只能涂一次的颜色中选一个,有 a 中种可能 
		// 选用能涂一下的颜色涂色,但是上一次用的是能涂 2 下的颜色
		// 那在这一次的时它会变成只能涂 1 下的颜色
		// 所以现在的 a 种能涂 1 下 的颜色,只能选 (a - 1) 种可能
	}
	if (b) {
		res = (res + (b - (last == 3)) * dfs(a + 1, b - 1, c, d, e, 2)) % P;
		// 涂 2 次的颜色少了一种,涂 1 次的颜色多了一种 
	}
	if (c) {
		res = (res + (c - (last == 4)) * dfs(a, b + 1, c - 1, d, e, 3)) % P;
	}
	if (d) {
		res = (res + (d - (last == 5)) * dfs(a, b, c + 1, d - 1, e, 4)) % P;
	}
	if (e) {
		res = (res + e * dfs(a, b, c, d + 1, e - 1, 5)) % P;
	}
	
	return dp[a][b][c][d][e][last] = res; 
}

int main () {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	memset(dp, -0x7f, sizeof(dp));
	inf = dp[0][0][0][0][0][0];
	
	int k; 
	cin >> k;
	int t[6] = {};
	for (int i = 1; i <= k; i ++) {
		int x;
		cin >> x;
		t[x] ++;
	}
	
	cout << dfs(t[1], t[2], t[3], t[4], t[5], 0) << "\n";
	
	return 0;
} 
相关推荐
西柚研究生12345613 小时前
论文分析15:跨层特征交互的多尺度无人机小目标检测算法
人工智能·算法·目标检测
rannn_11120 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
数模竞赛Paid answer20 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
不会代码的小猴21 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
青瓦梦滋1 天前
传输层UDP/TCP协议
linux·网络·c++·网络协议·tcp/ip·udp
AI备案指南-满满1 天前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案
江畔柳前堤1 天前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
一只旭宝1 天前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
良木林1 天前
子串 - LeetCode hot 100
算法·leetcode·职场和发展