R310 DIV2 C. Case of Matryoshkas
Chieh
posted @ 2015年6月28日 11:45
in codeforces
, 420 阅读
飞机票: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; }