传送门
题意:有n块糖,m种类型,并且每种类型的糖有一个限制Li,只能取>=Li或者0块糖,然后给出一个判定的标准S/C,S为所取糖的价值总和,C为所取的类型中数量最多的。
思路:如果C确定,那么对于每种糖,如果能取,我们必定是贪心取价值最大的,所以可能取C块,或者将其取完(总数<=C);如果每次枚举C都去暴力枚举贪心的话这样肯定是不可以的,开一个vector数组f,f[i]代表当C为i时还可以取得糖果,是相较于f[i-1]多取的。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define SZ(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-9;
const int maxn=1e5+5;
int T,n,m,l[maxn];
vector<int> v[maxn],f[maxn];
bool cmp(int x,int y) {return x>y;}
int main(){
std::ios::sync_with_stdio(0);
cin>>T;
while(T--){
cin>>n>>m;
rep(i,1,m) cin>>l[i];
int val,op;
rep(i,1,n){
cin>>val>>op;
v[op].pb(val);
}
rep(i,1,m){
sort(v[i].begin(),v[i].end(),cmp);
rep(j,0,SZ(v[i])-1) f[max((j+1),l[i])].pb(v[i][j]);
v[i].clear();
}
ll as=0,ac=1,ns=0,nc;
rep(i,1,n){
nc=i;
rep(j,0,SZ(f[i])-1) ns+=f[i][j];
if(ns*ac > nc*as) as=ns,ac=nc;
f[i].clear();
}
ll tp=__gcd(ac,as);
cout<<as/tp<<"/"<<ac/tp<<endl;
}
return 0;
}