【DP 优化】【分类讨论】[ABC176F] Brave CHAIN

从没见过,被暴打了。

很容易打一个暴力。fi,j,kf_{i,j,k} 表示取到第 i 次的时候,留下的两个值是 j,kj,k

这样复杂度是 O(n3)O(n^3)

以下将五个值分别说成 a,b,c,d,ea,b,c,d,e。对于每次询问,c,d,ec,d,e 是确定的。 考虑优化。观察式子,总共三种情况:

  1. c,d,ec,d,e 中全取。如果它们不相等,对于 ff 根本没影响。如果相等,所有状态全部 +1+1,其实也相当于没影响。后面的情况都不用讨论了,因为一定不更优。
  2. 取两个。令 b=c=db = c = d,更新的是 a,ea,e。只用枚举 aa,因为 bb 就是 c,dc,d。如果不强制 b,c,db,c,d 相等,那相当于 fa,xf_{a,x} 中取最大值。预处理即可。
  3. 取一个。令 a=b=ca = b = c,那就一种情况。如果不强制相等,那相当于 fx,xf_{x,x} 取最大值,同样预处理。

这样一来,我们的复杂度变为 O(n2)O(n^2)。所谓 O(状态×转移)O(状态 \times 转移) 不适用,因为一次可以处理很多种状态。这也启示我不能被所谓的传统思路限制了思维。

实现参考了 luogu 题解,挺好的。

关于实现,注意只讨论了枚举 aa 的情况,要时刻注意 fa,b=fb,af_{a,b} = f_{b,a},还要注意状态是否合法,比如开始的两个值是 1,21,2,则 f3,4f_{3,4} 就不合法。

/*
	- 别摆了
	- By yfz
*/

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3+10;
int f[N][N]; int p[N*3],n,mf[N];
struct D{
	int x,y,z;
};
int main() {
	for(auto c: {1, -1}) cout << c << endl;
	cin>>n;
	for(int i=1;i<=3*n;i++) cin>>p[i];
	memset(f,-0x3f,sizeof f); f[p[1]][p[2]] = f[p[2]][p[1]] = 0;
	memset(mf,-0x3f,sizeof mf); mf[p[1]] = mf[p[2]] = 0;
	int All_Plus = 0;
	
	queue<D>q;
	
	int ma = 0;
	for(int i=5;i<=3*n;i+=3) {
		int c = p[i-2], d = p[i-1], e = p[i];
		// 三个都选
		if(c == d && d == e) {All_Plus ++;continue;}
		
		// 选两个
		for(int a=1;a<=n;a++) q.push({a,e,mf[a]}), q.push({a,d,mf[a]}), q.push({a,c,mf[a]});
		if(c == d) {
			for(int a=1;a<=n;a++) q.push({a,e, f[a][c] + 1});
		}
		if(c == e) {
			for(int a=1;a<=n;a++) q.push({a,d, f[a][c] + 1});
		}
		if(d == e) {
			for(int a=1;a<=n;a++) q.push({a,c, f[a][d] + 1});
		}
		
		// 选一个 
		q.push({c,d, f[e][e] + 1});
		q.push({c,e, f[d][d] + 1});
		q.push({d,e, f[c][c] + 1});
		
		q.push({c,d, ma});
		q.push({c,e, ma});
		q.push({d,e, ma});
		while(!q.empty()) {
			auto [A,B,w] = q.front(); q.pop();
			ma = max(ma, f[B][A] = f[A][B] = max(f[A][B], w)); 
			mf[A] = max(mf[A],w); mf[B] = max(mf[B],w);
		}
	}
	int ans = 0;
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=n;j++) ans = max(ans,f[i][j] + (i == j && j == p[3*n]));
	}
	cout << ans + All_Plus;
	return 0;
}
posted @ 2024-10-08 20:52  cjrqwq  阅读(26)  评论(0)    收藏  举报  来源