视频解析:[蓝桥杯]真题讲解:接龙序列(暴力、线性DP)_哔哩哔哩_bilibili
题意
题目说了让我们最少删除多少个数保证序列为接龙序列。
我们倒推:最多保留多少个数,保证序列为接龙序列。
假设最多保留了res位数,那么就是最少要删除n-res位数,才可以保证序列为接龙序列。
思想
对于每一个数我们都有选和不选两种选择,因此我们总共有种选择。
我们可以将其画为一个树状图:
如果我们要选当前数,那么我们就要判断一下当前数是否合法,即当前数的最后一位数是否和下一个数的第一位数相同。如果合法,我们才能选择。
复杂度解析
次方是就是1e9多了,因此如果用dfs只能过20%的数据
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
#define int long long
int a[N];
int n,ans;
int get_first(int x)
{
int res = 0;
while (x)
{
res = x % 10;
x /= 10;
}
return res;
}
int get_last(int x)
{
int res = x % 10;
return res;
}
void dfs(int u,int cnt,int last)
{
if (u >= n) //i从0开始的,当i为n的时候说明所有的元素都处理完,我们选择一个保留最多的方案,那就是删除最少的方案
{
ans = max(ans,cnt);
return;
}
//选
if (last == -1 || get_last(last) == get_first(a[u])) //第一个数没选的时候last初始化为-1,表示可选可不选
{
dfs(u + 1, cnt + 1, a[u]); //第u位选择,考虑下一位 方案数+1 last更新为a[u]
}
dfs(u+1,cnt,last); //第u位不选 方案数不变 last不变
}
signed main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
dfs(0,0,-1);
cout << n - ans << endl;
return 0;
}