题解:P11876 [威海市赛2024] 收徒!
思维 + 问题转化 + 结合贪心思想的二分优化求最长不下降子序列 + 记录方案
在一张巨大的网格上,只能向右和向下移动,要求从起始位置移动到终点时最多能途径的物品数,考虑到一步关键转化 trick:将这些物品按照
由于要记录路径,于是考虑定义
相比 结合贪心思想的二分优化求最长上升子序列,本题是求最长不下降子序列,故你需要考虑将
因为
#define rep(x,y,z) for(int x=y;x<=z;x++)
const int N=2e5+5;
int h,w,n;
struct node{
int x,y;
bool operator<(node &t){
if(x==t.x) return y<t.y;
return x<t.x;
}
}p[N],ans[N<<1];
int f[N<<1];
int pre[N<<1],cur_idx[N<<1];
int cnt;
void dfs(int i){
if(!i) return;
dfs(pre[i]);
ans[++cnt]={p[i].x,p[i].y};
}
void solve(){
cin>>h>>w>>n;
rep(i,1,n) cin>>p[i].x>>p[i].y;
sort(p+1,p+1+n);
int len=1;
f[len]=p[1].y;
cur_idx[len]=1,pre[len]=0;
rep(i,2,n){
if(p[i].y>=f[len]){
pre[i]=cur_idx[len];
f[++len]=p[i].y;
cur_idx[len]=i;
}
else{
int j=upper_bound(f+1,f+1+len,p[i].y)-f;
f[j]=p[i].y;
cur_idx[j]=i;
pre[i]=cur_idx[j-1];
}
}
cout<<len<<endl;
ans[1]={1,1};
cnt=1;
dfs(cur_idx[len]);
ans[++cnt]={h,w};
rep(i,2,cnt){
int stepx=ans[i].x-ans[i-1].x;
int stepy=ans[i].y-ans[i-1].y;
while(stepx--) cout<<"D";
while(stepy--) cout<<"R";
}
}