Longest Unfriendly Subsequence题解证明
问题描述:
定义⼀个序列是杂乱的当且仅当其任意三个相邻的元素都互不相同。 给定序列 ,求其最⻓杂乱的⼦序列的⻓度。 注:子序列可以不连续,可视为原序列中删掉部分元素后得到的序列。
用 \(dp[x][y]\) 表示末尾两位为 \(x,y\) 的最长杂乱子序列的长度。对于每个 \(a_i\) 我们枚举 \(y\),则我们只需要维护 \(dp[x][y]\) 最大的两个 \(x\) 即可,分别为 \(x_1,x_2\,(dp[x_1][y]>=dp[x_2][y])\)。下为证明,若 \(x_1\neq a_i\),则 \(dp[x_1][y]>=dp[x_j][y]\),\(x_1\) 为最佳选择;若 \(x_1= a_i\),则 \(x_1\) 无法选择,\(dp[x_2][y]>=dp[x_j][y]\),\(x_2\) 为最佳选择。而 \(dp[x][y]\) 会转移成 \(dp[y][a_i]\),意味着 \(x\) 的选择不会影响接下来的转移。
接下来考虑 \(y\) 的选择,按题解所述,当状态转移到 \(a_i\) 时,我们只需维护以出现过的最后5个元素为末尾的5种状态。不妨假设这5种元素按顺序分别\(y_1,y_2,y_3,y_4,y_5\)。用反证法,我们假设需要维护的还有其他状态,末尾是 \(y_0\,(y_0\neq y_j)\)。接下来考虑由状态 \(dp[x][y_0]\) 转移过来的状态 \(dp[y_0][y_j]\)。不妨假设\(y_1,y_2\)分别与 \(dp[x][y_0]\) 维护的的2种 \(x\) 冲突,\(y_3\) 与 \(a_i\) 冲突,则至少存在\(dp[y_4][a_i]>dp[y_0][a_i],dp[y_5][a_i]>dp[y_0][a_i]\),由之前所证结论可知,以 \(a_i\) 为末尾的状态只需维护 \(y_4,y_5\) 两种,这与假设的还需维护 \(y_0\) 为末尾的状态相冲突,因此,结论得证。
点击查看代码
#define PII pair<int,int>
#define PIII pair<int,vector<PII>>
int a[N];
deque<PIII>dp[N];
void solve() {
cin >> n;
for (int i = 0; i <= n; i++) {
dp[i].clear();
}
dp[0].push_back({0,{{0,-1}}});
map<int,int>q;
int ans=0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
q.clear();
for(auto[y,u]:dp[i-1]){
if(y==a[i]){
for(auto [w,x]:u){
if(x!=a[i]){
q[x]=max(q[x],w);
}
}
continue;
}
for(auto [w,x]:u){
if(x!=a[i]){
q[y]=max(q[y],w+1);
}
}
}
int mx=-1,mxi=-1;
int mxx=-1,mxxi=-1;
for(auto[y,w]:q){
if(w>mx){
mxx=mx;
mxxi=mxi;
mx=w;
mxi=y;
}else if(w>mxx){
mxx=w;
mxxi=y;
}
}
ans=max(ans,mx);
dp[i].push_back({a[i],{}});
if(mx!=-1){
dp[i][0].second.push_back({mx,mxi});
}
if(mxx!=-1){
dp[i][0].second.push_back({mxx,mxxi});
}
for(auto[y,u]:dp[i-1]){
if(dp[i].size()==5)break;
if(y!=a[i]){
dp[i].push_back({y,u});
}
}
// for(auto[y,u]:dp[i]){
// cout<<y<<":\n";
// for(auto[w,x]:u){
// cout<<x<<"->"<<w<<' ';
// }cout<<endl;
// }
// cout<<endl;
}
cout<<ans<<endl;
}

浙公网安备 33010602011771号