题解 P4447 【[AHOI2018初中组]分组】
序
学长给的题,写完之后看题解貌似没有人和我的情况一样,就来写一波
思路
考虑每一个划分都可以由一个二元组来解释
其中
那么现在有一个数字
一个必要条件是
那么筛选下来的每个二元组的差别就只有
实现
先将
建立一个以
然后从
每一次从堆
不合法,更新
遇到
最后将
代码
以下代码在 https://www.luogu.com.cn/record/29511205 中提交 并 AC
#include <cstdio>
#include <queue>
#include <algorithm>
inline int Min( int a, int b ) { return a < b? a: b; }
int readin() {
int res = 0; char x = getchar();
while( x < '0' || x > '9' )
x = getchar();
while( x >= '0' && x <='9' ) {
res = res * 10 + ( x - '0' );
x = getchar();
}
return res;
}
const int N = 1e5 + 1e4;
struct node {
int len, la;
bool operator< ( const node &b ) const{
return this -> len > b.len;
}
};
int n, ans;
int a[N];
std::priority_queue<node> q;
std::queue<node> tmp;
int main() {
#ifdef woshiluo
freopen( "luogu.4447.in", "r", stdin );
freopen( "luogu.4447.out", "w", stdout );
#endif
n = readin();
ans = n;
for( int i = 1; i <= n; i ++ ) {
a[i] = readin();
}
std::sort( a + 1, a + n + 1 );
for( int i = 1; i <= n; i ++ ) {
if( a[i] != a[ i - 1 ] && i != 1 ) {
while( tmp.empty() == false ) {
q.push( tmp.front() );
tmp.pop();
}
}
bool flag = false;
while( q.empty() == false ) {
node top = q.top(); q.pop();
if( top.la + 1 == a[i] ) {
flag = true;
tmp.push( (node) { top.len + 1, a[i] } );
break;
}
else
ans = Min( ans, top.len );
}
if( !flag )
tmp.push( (node) { 1, a[i] } );
}
while( tmp.empty() == false ) {
q.push( tmp.front() );
tmp.pop();
}
while( q.empty() == false ) {
node top = q.top(); q.pop();
ans = Min( ans, top.len );
}
printf( "%d\n", ans );
}