codeforces 556C. Case of Matryoshkas 解题报告

题目链接:http://codeforces.com/contest/556/problem/C

题目意思:有 n 个数(1,2,...,n)组成 k 条链。第 i 条链由 mi 个数组成。每一秒只可以做其中一件事:(1)将链i连到只有一个数的链 j 中(链 i 的最大值比只由单个数组成的链 j 还要小);(2)将链上最大的数从链中分离。 然后我们最终是要得到一条1,2,3,。。。n。问最少需要连接的秒数。

  不难推出,我们需要找到编号为 1 的链包含多少个数,然后对于此链的其他数,我们需要先分离然后连接。其他链也需要先分离再连接,注意,对于某条含有 x 个数的链,分离的秒数为 x - 1,而连接的秒数为 x 。 那现在问题就转化为如何找出包含 1 的链最长为多少(数是连续的!)

  假设包含 1 的链为 cnt,那么最少的秒数应为 2(n - (k-1) - cnt) + (k-1) 。2(n - (k-1) - cnt) 这个表示所有需要分离和连接的总数,但由于每条链分离秒数是比连接的秒数少1的,所以需要加回 k -1 !

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 inline int Getint()
 9 {
10     char ch = getchar();
11     while (ch < '0' || ch > '9')
12         ch = getchar();
13     int ret = 0;
14     while (ch >= '0' && ch <= '9') {
15         ret = ret * 10 + ch - '0';
16         ch = getchar();
17     }
18     return ret;
19 }
20 
21 int main()
22 {
23     #ifndef ONLINE_JUDGE
24         freopen("in.txt", "r", stdin);
25     #endif // ONLINE_JUDGE
26 
27     int n, k, m, a;
28  // while (scanf("%d%d", &n, &k) != EOF) {
29         n = Getint(), k = Getint();
30         int cc = 0;
31         for (int i = 0; i < k; i++) {
32             m = Getint(), a = Getint();
33             int cnt = 0;
34             if (a == 1) {
35                 cnt = 1;  // 序列第一个数就是 1 ,否则就是序中或序尾出现 1
36             }
37             for (int j = 2; j <= m; j++) {
38                 a = Getint();
39                 if (cnt == j-1 && a == j) {
40                     cnt++;
41                 }
42             }
43             if (cnt) cc = cnt;
44         }
45         printf("%d
", 2*(n-(k-1)-cc)+(k-1));
46  // }
47     return 0;
48 }
View Code
原文地址:https://www.cnblogs.com/windysai/p/4641731.html