1. 程式人生 > 其它 >21.6.2 t1

21.6.2 t1

tag:貪心,堆


可以發現一個狀態的後繼狀態一定為

  • \(a_{mx+1}\)
  • \(a_{mx+1}\) 並丟掉 \(a_{mx}\)

#include<bits/stdc++.h>
using namespace std;

template<typename T>
inline void Read(T &n){
	char ch; bool flag=false;
	while(!isdigit(ch=getchar()))if(ch=='-')flag=true;
	for(n=ch^48;isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48));
	if(flag)n=-n;
}

typedef long long ll;

enum{
    MAXN = 200005
};

struct pr{
    ll sum; int sz, mx;
    pr(ll sum=0, int sz=0, int mx=0):sum(sum),sz(sz),mx(mx){}
    inline bool operator <(const pr &k)const{return sum*k.sz>sz*k.sum;}
};
priority_queue<pr>q;

int n, k, a[MAXN];

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}

inline void print(ll x, ll y){
    ll g = gcd(x,y);
    printf("%lld/%lld\n",x/g,y/g);
}

int main(){
    Read(n); Read(k);
    for(register int i=1; i<=n; i++) Read(a[i]);
    sort(a+1,a+n+1);
    q.push(pr(a[1],1,1));
    while(k--){
        pr cur = q.top(); q.pop();
        print(cur.sum,cur.sz);
        if(cur.mx!=n)
            q.push(pr(cur.sum+a[cur.mx+1]-a[cur.mx],cur.sz,cur.mx+1)),
            q.push(pr(cur.sum+a[cur.mx+1],cur.sz+1,cur.mx+1));
    }   
    return 0;
}