jzoj 3853. 帮助Bsny(help)(或帮助Bubu)

原题,以前做过。
但已经不会了。(所以现在回来补题解了
(f[i][j][k][s])表示到第(i)本,抽出了(j)本,然后最后一本为类型(k),前面已有本子的二进制状态为(s)的最小混乱值。
转移显然,求答案的时候看看当前状态如果有的类型本子没有出现(设有(x)本),那么答案要多加(x)。(因为它抽出以后不能放到同本子处,只能另开一个混沌空间(笑))

Code

#include <cstdio>
#include <cstring>
#define N 110
#define inf 168430090
#define small(x, y) (x = x < y ? x : y)
#define min(x, y) (x < y ? x : y)
#define mem(x, a) memset(x, a, sizeof x)
#define fo(x, a, b) for (register int x = (a); x <= (b); x++)
#define fd(x, a, b) for (register int x = (a); x >= (b); x--)
using namespace std;
int n, K, a[N], tag[9], cf[N];
int f[N][N][9][257], ans;

template<typename T>
inline void read(T& x)
{
	x = 0; char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
}

int main()
{
	freopen("help.in", "r", stdin);
//	freopen("help.out", "w", stdout);
	read(n), read(K);
	cf[0] = 1; ans = n;
	fo(i, 1, 8) cf[i] = cf[i - 1] << 1;
	fo(i, 1, n) read(a[i]), a[i] -= 25, tag[a[i]]++;
	mem(f, 5);
	f[1][0][a[1]][cf[a[1]]] = 1;
	f[1][1][8][0] = 0;
	fo(i, 1, n - 1)
		fd(j, min(i, K), 0)
			fo(k, 0, 8)
				fo(l, 0, cf[8] - 1)
				{
					if (f[i][j][k][l] == inf) continue;
					if (a[i + 1] == k) small(f[i + 1][j][k][l], f[i][j][k][l]);
					else small(f[i + 1][j][a[i + 1]][l | cf[a[i + 1]]], f[i][j][k][l] + 1);
					if (j < K) small(f[i + 1][j + 1][k][l], f[i][j][k][l]);
				}
	fo(i, 0, cf[8] - 1)
	{
		int t = 0;
		fo(j, 0, 8) t += (tag[j] && ((i & cf[j]) == 0));
		fo(k, 0, 8) small(ans, f[n][K][k][i] + t);
	}
	printf("%d
", ans);
	return 0;
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/12203405.html