CodeForces 1020C
这
题
其
实
挺
好
像
,
发
现
数
据
范
围
很
小
,
直
接
模
拟
就
行
了
这题其实挺好像,发现数据范围很小,直接模拟就行了
这题其实挺好像,发现数据范围很小,直接模拟就行了
b
u
t
这
题
我
不
是
在
C
F
上
打
的
,
看
不
到
数
据
点
,
有
个
细
节
真
的
没
想
到
but这题我不是在CF上打的,看不到数据点,有个细节真的没想到
but这题我不是在CF上打的,看不到数据点,有个细节真的没想到
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=3010;
int n,m,mx=0,mn=1e9+5;
int p[N],c[N];
ll sum[N][N];
vector <int> val[N];
vector <int>::iterator it;
int tp[N];
bool ff[N];
int stat[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&p[i],&c[i]);
val[p[i]].push_back(c[i]);
}
for(int i=1;i<=m;i++){
if(val[i].empty()) continue;
sort(val[i].begin(),val[i].end());
int j=0;
int len=val[i].end()-val[i].begin();
if(i!=1)mx=max(mx,(len));
for(it=val[i].begin();it<val[i].end();it++){
sum[i][++j]=sum[i][j-1]+(*it);
}
}
for(int i=1;i<=m;i++){
if(!val[i].empty())mn=min(mn,(*val[i].begin()));
}
int s1=val[1].size();//真心希望联赛不要这么坑,真的没有想到还能这样,要不是上CF看原数据点,我觉得我调十天都调不出来
if(mx==0&&(!val[1].empty())){
puts("0");
exit(0);
}
if(mx==0){
printf("%d",mn);
exit(0);
}
if(s1>mx){
puts("0");
exit(0);
}
ll ans=1234567890000000;
for(int i=s1;i<=mx+1;i++){
ll sums=0;
int s=s1;
memset(ff,0,sizeof(ff));
bool flag=false;
for(int j=2;j<=m;j++){
int siz=val[j].end()-val[j].begin();
if(siz>=i){
ff[j]=1;stat[j]=siz-i+2;
sums+=sum[j][siz-i+1];
s+=siz-i+1;
}
if(s>i){
flag=true;
break;
}
}
if(flag){
continue;
}
if(s<i)
{
memset(tp,0,sizeof(tp));
int cnt=0;
for(int j=2;j<=m;j++){
if(ff[j]){
it=val[j].begin()+stat[j]-1;
if(it<val[j].end()){
for(it;it<val[j].end();it++){
tp[++cnt]=*it;
}
}
continue;
}
for(it=val[j].begin();it<val[j].end();it++){
tp[++cnt]=*it;
}
}
sort(tp+1,tp+cnt+1);
int ttp=i-s;
for(int i=1;i<=(ttp);i++){
sums+=tp[i];
}
}
ans=min(ans,sums);
}
printf("%lld",ans);
}