蓝桥杯2023年第十四届省赛真题-接龙数列

2023-05-10 20:48:56    动态资讯   

试题E: 接龙数列

题意描述

对于一个长度为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

要求使得数列变成接龙数列的最少删除个数, 相当于求该数列的最长接龙子数列的长度, 用总长度减去最长接龙长度即为最少删除个数。

定义$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;
}