Question description
For an integer sequence of length K: A1, A2, . . . , AK, we call it a solitaire sequence if and only if the first digit of Ai is exactly equal to the last digit of Ai−1 (2 ≤ i ≤ K).
For example, 12, 23, 35, 56, 61, 11 is a solitaire sequence; 12, 23, 34, 56 is not a solitaire sequence because the first digit of 56 is not equal to the last digit of 34. All integer sequences of length 1 are solitaire sequences.
Now given a sequence A1, A2, . . . , AN of length N, please calculate the minimum number of numbers that can be deleted from it so that the remaining sequence is a solitaire sequence?
analyze
Similar to the longest rising subsequence problem
You can choose which number for the penultimate number (ending with a[j]) to divide the set into several categories (don’t choose until you choose the number a[i - 1])
f[i] represents the set of all solitaire sequences ending with a[i]
The last digit of the jth number is equal to the first digit of the current number
Timeout code:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
char s[N], l[N], r[N];
long long n, res, f[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> s;
l[i] = s[0], r[i] = s[strlen(s) - 1];
}
for(int i = 1; i <= n;i ++)
{
f[i] = 1;
for(int j = 1; j < i; j ++)
{
if(l[i] == r[j])f[i] = max(f[j] + 1, f[i]);
res = max(res, f[i]);
}
}
cout << n - res;
return 0;
}
Define dp[i] as the longest number of solitaires ending with dp[i]. Subtract the longest number of solitaires from the total length to determine the number to be deleted.
Ending with l[i] means that the beginning of the next number is l[i], so the end of the next number is r[i], so it can be l[i] + 1
AC code:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
char s[N];
long long n, res, dp[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> s;
int l = s[0] - '0', r = s[strlen(s) - 1] - '0';
dp[r] = max(dp[r], dp[l] + 1);
res = max(res, dp[r]);
}
cout << n - res;
return 0;
}