Chieh's Blog

Because Of Coding

R310 DIV2 C. Case of Matryoshkas

Chieh posted @ 2015年6月28日 11:45 in codeforces , 404 阅读

飞机票:http://codeforces.com/contest/556/problem/C

题意:就是给你k个已经按大小递增的序列,每个有mi个1<=mi<=n,m1+m2+,,mk=n,其中1到n只出现一次。求组合成从1到n的序列最小的时间值,具体的每秒能做的事是,把序列拆掉或把序列合并,拆掉的话必须有一个是独立的不能两个子序列一起拆开,比如序列1-2-3-4,可以把1或4拆下来,但是不能拆成1-2 3-4这样是非法的。合并的话也是有规律的,就是以1为首的字串不能何在一个序列长度大于1的序列里面,这样也是非法的,比如序列1-2-3 和序列5-6合并成1到6要3秒,因为5-6包含2长度,所以要拆开,成为5和6,然后5合并,6合并。题意比较坑爹啊~

分析:知道题意后就可以瞎搞了,很简单,就是把包含1的序列后面能递增到几个拿出来先,如果后面没了,初始时间就是0,如果后面还有就是1,因为要拆开,然后后面的序列都要拆,因为要把包含1的合并进去,所以假设序列长度为len,则拆要len-1,合并要len,所以共要len*2-1,所有加起来就是答案,然后啪啪啪就可以AC了

 

/*
Author:Chieh
Because Of Coding
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#define LL long long
#define INF 1e9
#define EPS 1e-9
using namespace std;
const int maxn=123456;
int idx[maxn];
vector<int> V[maxn];
int first[maxn];
int n,k;
LL MIN;
void init()
{
    int m;
    MIN=0;
    for(int i=1; i<=k; i++)
    {
        V[i].clear();
        first[i]=0;
        scanf("%d",&m);
        bool flag=1;
        for(int j=1; j<=m; j++)
        {
            int u;
            scanf("%d",&u);
            if(u==1)
            {
                flag=0;
                int p=1;
                for(int z=j+1; z<=m; z++)
                {   j=z;
                    scanf("%d",&u);
                    if(u==++p)continue;
                    MIN+=(m-z+1)*2;
                    break;
                }
            }
        }
        if(flag){
            MIN+=(m*2)-1;
        }
    }
}
void play()
{

    printf("%I64d\n",MIN);

}
int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        init();
        play();
    }
//   cout << "Hello world!" << endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter