[CodeForces 743E] Vladik and cards(二分答案 + 状压 DP) | 错题本

文章目录

题目

[CodeForces 743E] Vladik and cards

分析

首先看到“任意两种数的数量相差不超过 1 1 ”,并且只有 8 8 种数,考虑状压每种数是 0 0 x x 还是 x + 1 x + 1 ,然后发现是 x x 还是 x + 1 x + 1 不重要,转移的时候看一下哪种选法更优即可,因为某种数数量是否多 1 1 是无后效性的。但是 x x 需要枚举,然后观察发现 x x 显然可以二分。于是有了一个初步发想法是二分 x x 并状压 DP 检验。 D p [ i ] [ S ] Dp[i][S] 表示前 i i 个数,选的数的种类的集合为 S S 的最长子序列长度。预处理每种数在原序列中的位置,转移的时候往里面塞 x x x + 1 x + 1 个当前数即可。

据说可以二分 + 暴力 O ( n log n 8 ! ) O(n\log n \cdot 8!) 水过去。

代码

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>

const int MAXN = 1000;
const int MAXA = 8;

int N;
int A[MAXN + 5];
std::vector<int> Pos[MAXA + 5], Tmp[MAXA + 5];

int Dp[MAXN + 5][(1 << MAXA) + 5];

int Check(int num) {
	for (int i = 1; i <= MAXA; i++)
		Tmp[i] = Pos[i];
	memset(Dp, -0x3f, sizeof Dp);
	Dp[0][0] = 0;
	for (int i = 0; i < N; i++) {
		int lim = (1 << MAXA) - 1;
		for (int j = 0; j <= lim; j++) {
			if (Dp[i][j] >= 0) {
				for (int k = 0; k < MAXA; k++)
					if (!(j & (1 << k))) {
						if (Tmp[k + 1].size() > num)
							Dp[Tmp[k + 1][num]][j | (1 << k)] = std::max(Dp[Tmp[k + 1][num]][j | (1 << k)], Dp[i][j] + 1);
						if (Tmp[k + 1].size() >= num)
							Dp[Tmp[k + 1][num - 1]][j | (1 << k)] = std::max(Dp[Tmp[k + 1][num - 1]][j | (1 << k)], Dp[i][j]);
					}
//				printf("%d %d %d\n", i, j, Dp[i][j]);
			}
		}
		if (A[i])
			Tmp[A[i]].erase(Tmp[A[i]].begin());
	}
	int res = -1;
	for (int i = 1; i <= N; i++)
		res = std::max(res, Dp[i][(1 << MAXA) - 1]);
	if (res == -1)
		return -1;
	return num * 8 + res;
}

int main() {
	scanf("%d", &N);
	for (int i = 1; i <= N; i++) {
		scanf("%d", &A[i]);
		Pos[A[i]].push_back(i);
	}
	for (int i = 1; i <= MAXA; i++)
		if (!Pos[i].size()) {
			int Ans = 0;
			for (int j = 1; j <= MAXA; j++)
				if (Pos[j].size())
					Ans++;
			return printf("%d", Ans), 0;
		}
	int lft = 1, rgt = N / 8 + 1;
	while (lft + 1 < rgt) {
		int mid = (lft + rgt) >> 1;
		if (~Check(mid))
			lft = mid;
		else
			rgt = mid;
	}
	printf("%d", Check(lft));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C20190102/article/details/107694634
今日推荐