题解:P14556 [ROI 2013 Day2] 星际航程
P14556 [ROI 2013 Day2] 星际航程
提供一个不一样的思路。
令最大的
朴素转移是
code
#include<iostream>
#include<vector>
using namespace std;
const int N=3e5+5;
int a[N],las[N],L[N],dp[N],st[N],tt,f[N],n;
vector<int>p;
void path(int id){
p.push_back(id);
if(id==1) return;
path(f[id]);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
L[i]=las[a[i]];
las[a[i]]=i;
}
dp[1]=0;st[++tt]=1;
for(int i=2;i<=n;i++){
int l=1,r=tt,ans=i;
if(!L[i]){//不可做为线段终点
dp[i]=1e9;
goto EN;
}
while(l<=r){
int mid=(l+r)>>1;
if(st[mid]>=L[i])
r=mid-1,ans=min(ans,st[mid]);
else l=mid+1;
}
f[i]=ans;
dp[i]=dp[ans]+1;
EN:;
while(tt>0&&dp[st[tt]]>=dp[i]) --tt;
st[++tt]=i;
}
if(dp[n]>=1e9){
cout<<0;
return 0;
}
cout<<dp[n]<<'\n';
path(n);
for(int i=p.size()-2;i>=0;i--)//注意不用输L[1],并且要倒着输
cout<<L[p[i]]<<' ';
return 0;
}