1单词接龙
将新加入的单词和已经存在的求一个最长前后缀,重复的去掉加入去重后的字符即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long ll;
const int max_n = 1e7 + 10;
char ans[max_n], s[max_n];
ll kmp[max_n];
ll minn, top, len1, len2,n;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%s", s + 1);
len1 = strlen(s + 1);
top = len1;
minn = min(len1, len2);
s[++top] = '?';
kmp[0] = kmp[1] = 0;
int j = 0;
for (int j = 1; j <= minn; j++)
s[++top] = ans[len2 - (minn - j)]; //将ans中最大可以与s匹配的连接起来
for (int j = 1; j < top; j++)//用kmp计算他们最大的前后缀
{
ll k = kmp[j];
while (k && s[k + 1] != s[j + 1])
k = kmp[k];
if (s[k + 1] == s[j + 1])
k++;
kmp[j + 1] = k;
}
for (int j = kmp[top] + 1; j <= len1; j++)// j = kmp[top] + 1的到最长前后缀
ans[++len2] = s[j];
}
for (int i = 1; i <= len2; i++)
cout << ans[i];
return 0;
}
2、最长递增子序列
动态规划,从前往后打表,算出每一个数之前最长子序列
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int dp[3000];
int ans=1;
for(int i=0;i<nums.size();i++)
{
dp[i]=1;//最小为1
for(int j=0;j<i;j++)
{
if(nums[j]<nums[i])dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,dp[i]);
}
return ans;
}
};