枚举获胜状态即可
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<cstdlib> #include<queue> #include<set> #include<map> #include<stack> #include<ctime> #include<vector> #define INF 0x3f3f3f3f #define PI acos(-1.0) #define N 10001 #define MOD 1e9+7 #define E 1e-6 #define LL long long using namespace std; struct Node{ int num; int value; }a[N]; int bucket[N]; int ticket[N]; int cmp(Node x,Node y) { return x.value<y.value; } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].num,&a[i].value); bucket[a[i].num]++;//最开始的投票情况 } sort(a+1,a+n+1,cmp); long long minn=999999999999,sum=0,ans; for(int i=bucket[1];i<=n;i++)//枚举获胜状态 { sum=0; ans=0; for(int j=2;j<=m;j++) { if(bucket[j]>=i) { ticket[j]=bucket[j]-i+1;//要赢此选手需要在其处买的票数 sum+=ticket[j];//记录要买的总票 } else ticket[j]=0; } if(i-bucket[1]<sum) continue; sum=i-bucket[1]-sum; //记录要在比1号低的选手买的票数 for(int j=1;j<=n;j++) { if(ticket[a[j].num]!=0)//比1号高 { ticket[a[j].num]--; ans+=a[j].value; } else { if(sum!=0&&a[j].num!=1)//低且需要买票 { sum--; ans+=a[j].value; } } } minn=min(minn,ans);//取最优 } cout<<minn<<endl; return 0; }