A. Card game
time limit per test1 second
memory limit per test64 megabytes
The Olympic Games in Paris are almost here, and you are thrilled! You and four of your friends managed to get five of the rare tickets for sports climbing even though all tickets were sold out in less than two hours! While waiting for the games to start, you decide to do something fun to keep your mind off the wait: play your favourite card game.
The card deck contains four standard suits of different colours: silver (S), white (W), emerald (E), and red (R), as well as one trump suit coloured cyan (C). That is, the Cyan cards outrank all other cards. There are N cards of each suit, numbered from 1 to N. This means that, in total, the deck comprises 5N cards. At the beginning of the game, the deck is randomly distributed between the five players, such that each player gets N cards.
Before you start playing, you want to organise your cards such that all cards of the same suit are next to each other in increasing order, and the trump cards appear at the end (also in increasing order). When you receive your cards, they appear in your hand as a sequence. To organise them, you perform a sequence of actions, where in each action you take one card out of your hand and put it back in your hand at another position (between two cards, before the first card, or after the last card).
You cannot help but wonder: what is the minimum number of actions you need to take in order to organise your hand?
Input
The input consists of two lines. The first line contains the number N. The second line contains N space-separated values describing the sequence of cards in your hand. Each value is composed of one letter of the set {S, W, E, R, C} (describing the card suit), followed by an integer V such that 1≤V≤N (describing the card number).
Limits
1≤N≤100000
Output
The output should contain a single line, consisting of a single number: the minimum number of actions required to organise your hand.
Examples
Input
4
C1 R2 E4 R1
Output
2
Input
5
S2 W4 E1 R5 C1
Output
0
【思路分析】
思维+LIS。本题为区域赛银牌题。
显然存在某一子序列不需要移动,对于同一种花色,需要找到最长递增子序列(LIS)。对同一种花色,代价为M-LIS,M代表该花色卡片数量。
显然只考虑一种花色是不完整的,每个花色的情况不相互独立。对于每种花色,对于其上数字+k*n,k为0,1,2,3,这样可消除花色的影响。只需要枚举4!种全排列情况即可。对于C,数字始终+4n,这样可使得花色为C的卡片始终在末尾。
对于LIS,采用的算法为线性dp+二分。故本题的时间复杂度为.
#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <cmath>
#include <algorithm>
#include <climits>
#include <stack>
#include <cstring>
#include <iomanip>
#include <set>
#include <queue>
#define i64 long long
using namespace std;
i64 LIS(pair<char, i64> arr[], i64 n) {
i64 dp[n], len = 0;
dp[0] = arr[0].second;
for (int i = 0; i < n; ++i) {
if (arr[i].second > dp[len]) dp[++len] = arr[i].second;
else *(lower_bound(dp, dp + len, arr[i].second)) = arr[i].second;
}
return len + 1;
}
void solve() {
i64 n, maxn = 0;
cin >> n;
pair<char, i64> arr[n];
i64 ptt[4] = {0, n, 2 * n, 3 * n};
for (int i = 0; i < n; ++i) cin >> arr[i].first >> arr[i].second;
do {
pair<char, i64> tmp[n];
for (int i = 0; i < n; ++i) tmp[i] = arr[i];
for (auto &it2: tmp) {
if (it2.first == 'S') it2.second += ptt[0];
else if (it2.first == 'W') it2.second += ptt[1];
else if (it2.first == 'E') it2.second += ptt[2];
else if (it2.first == 'R') it2.second += ptt[3];
else it2.second += 4 * n;
}
maxn = max(maxn, LIS(tmp, n));
} while (next_permutation(ptt, ptt + 4));
cout << n - maxn;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}