对于一个长度为K 的整数数列:$A1,A_2..A_K$,我们称之为接龙数列当且仅当$A_i$ 的首位数字恰好等于$A{i−1}$ 的末位数字(2 ≤ i ≤ K)。
例如$12,23,35,56,61,11$ 是接龙数列;$12,23,34,56$ 不是接龙数列,因为56的首位数字不等于34 的末位数字。所有长度为1 的整数数列都是接龙数列。
现在给定一个长度为N 的数列$A_1,A_2… A_N$,请你计算最少从中删除多少个数,可以使剩下的序列是接龙序列?
要求使得数列变成接龙数列的最少删除个数, 相当于求该数列的最长接龙子数列的长度, 用总长度减去最长接龙长度即为最少删除个数。
定义$dp[i][j]$为前i
个数中, 以数字j
结尾的最长接龙数列的长度。
设第i
个数的首位数字是a, 末位数字是b。 则$dp[i]$中相对于$dp[i-1]$可能发生变化的只有$dp[i][b]$, 因为第i个数可能加到一个以a结尾的接龙数列中, 使得这个接龙数列长度加1并且结尾数字变成b
.
所以状态转移方程为dp[i][b] = max(dp[i - 1][b], dp[i - 1][a] + 1)
#include <bits/stdc++.h> using namespace std; int dp[10]; int main () { int n, mx = 0; cin >> n; for (int i = 0; i < n; i ++) { string s; cin >> s; int a = s[0] - '0', b = s.back() - '0'; dp[b] = max(dp[b], dp[a] + 1), mx = max(mx, dp[b]); } cout << n - mx << endl; return 0; }