欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 【2024.10.28练习】游园安排

【2024.10.28练习】游园安排

2025/5/3 4:08:16 来源:https://blog.csdn.net/FeAtherHZM/article/details/143305197  浏览:    关键词:【2024.10.28练习】游园安排

题目描述


题目分析

这是一道用DP解决的最长上升子序列(LIS)问题。

时间复杂度为O(n^2)的解法:

定义dp[i]为“以name_i为末尾的最长上升子序列长度”,状态转移方程为:

dp[i]=max\left \{ 1,dp[j]+1 \ | \ j<i,name_j<name_i \right \}

由于这种递推方法需要往回看字典序比自己小的名字,因此在本题中采用会超时。


时间复杂度为O(n*logn)的解法:

定义dp[i]为“长度为i+1的上升子序列中末尾元素的最小值”(不存在的话字符串为十个Z以确保最大)

状态转移方程为:

dp[i]=min\left \{ dp[i],name_j \ |\ i=0\cup name_j>dp[i-1]\right \}

由于对于每个name_j,都要从0到i的dp数组更新一遍,因此时间复杂度仍然为O(n^2)。

但dp数组在这里的特点是有序递增,因此可以用二分查找优化算法。

使用该算法得到的结果子序列就是从第一个名字开始依次字典序最小的方案。


求出具体子序列:

要实现该动态规划的回溯很简单,定义一个前驱数组pre[i]即可,该数组记录了name_i作为某条子序列末尾元素时上一个元素的下标。


我的代码

注意题目细节:游客可能重名,而子序列又要求前一个必须严格小于后一个,因此通过upper_bound()函数找到dp[i]时注意看dp[i-1]是否等于当前名字,若是则不更新dp[i]的值;而使用lower_bound()就不会出现此问题。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
string s;
string name[1000002];
string dp[1000002];
int dp_2[1000002];
int pre[1000002];
int N;
void init(){for(int i=0;i<N;i++){dp[i]="zzzzzzzzzzz";pre[i]=0x3f3f3f3f;}
}
int split(string str){int n=0;name[n]+=str[0];for(int i=1;i<str.length();i++){if(str[i]<='Z'&&str[i]>='A') n++;name[n]+=str[i]; }return (n+1);
}
int main(void)
{cin>>s;N=split(s);init(); //Binary Searchfor(int i=0;i<N;i++){int pos = lower_bound(dp,dp+N,name[i])-dp;dp[pos]=name[i];dp_2[pos]=i;if(pos!=0) pre[i]=dp_2[pos-1];} //Ourput Answerint t=0;for(int i=0;i<N;i++){if(dp[i]=="zzzzzzzzzzz"){t=dp_2[i-1];break;	}}stack<int> ans;ans.push(t);while(pre[t]!=0x3f3f3f3f){t=pre[t];ans.push(t);}while(ans.size()){cout<<name[ans.top()];ans.pop();}return 0;
}


思路扩展

这里为了求出最长子序列建立了前驱数组。但也可以建立一个ans[i]字符串数组,代表了长度为i+1的最小字典序子序列。状态转移方程如下:

每当dp[i]更新时,若i=0,ans[i]=name[i];若i>0,ans[i]=ans[i-1]+name[i]。最终输出结果直接输出最大i对应的ans[i]即可。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词