题意:现在有m种糖,n颗糖,每一颗糖有俩个属性,一个是所属种类,一个是自身价格。对于每一种糖,最少要取least[i]颗,现在我们定义图片说明
S代表我们取的糖果的价格总和,C代表我们在所取得糖的类型中,取的最多的糖果的种类取了多少个
现在我们要求Value的最大值
首先价格总和要最大,简单贪心就是在同一种类型的糖中,选价格越大的越好
其次考虑整体,分母要尽量小,那我就对于每一个不同的分母,分散到各个组,都取其最大的前i个
举个例子,现在每一种糖果的least都为2图片说明
从least开始算,每次算一次价值,比较怎么取价值更高即可

#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const ll maxn=1e5+5;
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; } ;
int least[maxn];
vector<int>vec[maxn],presum[maxn];

bool cmp(int a,int b){return a>b;}

int main()
{
    int _;_=read();while (_--)
    {
        int n=read(),m=read();
        for(int i=1;i<=m;i++) least[i]=read();
        for(int i=1;i<=n;i++)
        {
            int x=read(),y=read();
            vec[y].push_back(x);
        }
        for(int i=1;i<=m;i++)
        {
            sort(vec[i].begin(),vec[i].end(),cmp);
            for(int j=0;j<vec[i].size();j++) presum[max(j+1,least[i])].push_back(vec[i][j]);
            //vec[i][j]+=vec[i][j-1];
        }
        //for(int i=0;i<presum[3].size();i++) cout<<presum[3][i]<<' ';
        //puts("");
        ll preans=0,precnt=1,nowans=0,nowcnt=1;
        for(int i=1;i<=n;i++)
        {
            nowcnt=i;
            for(int j=0;j<presum[i].size();j++) nowans+=presum[i][j];
            //cout<<nowans<<endl;
            if(nowans*precnt>preans*nowcnt)    preans=nowans,precnt=nowcnt;
            presum[i].clear();
        }
        ll g=__gcd(preans,precnt);
        cout<<preans/g<<"/"<<precnt/g<<endl;
        for(int i=1;i<=m;i++) vec[i].clear();
    }
}
/*
 15 4
 2 2 2 2
 6 1
 4 1
 3 1
 2 1
 1 1
 7 2
 3 2
 2 2
 5 3
 4 3
 1 3
 8 4
 3 4
 2 4
 1 4
 */