洛谷p4447

https://www.luogu.com.cn/problem/P4447

题意:

把每个数字尽可能分到一个组中,从这些组里面选出长度最小的分组;分组规则是连续的数字比如1234

思路:

可以先将数组排序,同时要满足数字连续,以及尽量让数组长度较大,所以可以每次选择长度最小的数组进行拼接,同时还要满足拼接规则,所以优先在结尾等于a[i]-1的分组中选取长度最小的进行拼接,因为已经排序,所以结尾小于a[i]-1的分组已经不能进行拼接,可以直接跳过,这样的一个操作可以通过优先队列来实现,通过维护区间长度以及区间的结尾,优先选取满足条件结尾最小中长度最小,

题解:

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int N=100010;
int a[N];
struct T{
    int len,lst;
    bool operator<(const T&t)const{//优先选择结尾,然后选择长度
        if(lst!=t.lst) return lst>t.lst;
        return len>t.len;
    }
};
void solve() {
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    priority_queue<T> q;
    sort(a+1,a+1+n);
    int res=1e9;
    for(int i=1;i<=n;i++){
        while(q.size() and q.top().lst<a[i]-1)  res=min(res,q.top().len),q.pop();
        if(q.empty() or q.top().lst==a[i]){
            q.push({1,a[i]});
        }else{
            auto &[x,y]=q.top();
            q.pop();
            q.push({x+1,y+1});
        }
    }
    while(q.size()){
        auto &[x,y]=q.top();
        res=min(res,x);
        q.pop();
    }
    cout<<res<<endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);
    //int _; cin >> _; while (_--) 
    solve();
    return 0;
}
posted @ 2021-10-05 22:40  指引盗寇入太行  阅读(177)  评论(0编辑  收藏  举报