zoukankan      html  css  js  c++  java
  • CodeForces 1019A Elections|贪心

    题目链接
    题目大意:
    因zz不正确做了特殊处理

    (n)voter(m)Party。每个voter会投给一个Party(p_i),同时,若给(c_i)money,则会投给你指定的某个Party,现在给出每个voter的情况,求(1)Party要赢需要给voter共多少钱。一个Party要胜利当且仅当其获得票数比其他都要多。

    (1le n,mle 3000)

    题目思路:

    本题难点在于,改选后得票最大这一称号可能易主。这同时导致了收拢(c_i)最小的人的贪心策略不正确。

    那么我们需要规避这个问题。一个灵光一闪的想法是枚举其他Party最大得票数,若超过则按(c_i)由小到大砍掉多余票数。显然,此时(1)Party需要比最大得票数多(1),如果砍完票数后不满足条件,则从(p_i eq 1)未被选择(i)中选择(c_i)最少的voter直到票数满足要求。

    本题的(n m)规模较小,因此枚举即可。时间复杂度(O(n^2logn))

    上代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,cnt[3010],net[3010],fr[3010];bool vis[3010];
    struct voter
    {
    	int p;long long c;
    }a[5000];
    bool cmp(voter x,voter y)
    {
    	return x.c>y.c;
    }
    int main()
    {
    	cin>>n>>m;
    	for (int i=1;i<=n;i++) 
    	{
    		cin>>a[i].p>>a[i].c;
    	}
    	sort(a+1,a+n+1,cmp);
    	int maxx=0;
    	for (int i=1;i<=n;i++)
    	{
    		cnt[a[i].p]++;maxx=max(maxx,cnt[a[i].p]);
    		net[i]=fr[a[i].p];fr[a[i].p]=i;
    	}
    	long long ans=3000*1e9;
    	for (int i=maxx;i>=0;i--)
    	{	
    		int l=i+1-cnt[1];long long s=0;
    		for (int j=1;j<=n;j++) vis[j]=false;
    		for (int j=2;j<=m;j++)
    		{
    			if (cnt[j]>i) 
    			{
    				int tmp=cnt[j];
    				for (int k=fr[j];k;k=net[k])
    				{
    					s+=a[k].c;vis[k]=true;
    					tmp--;l--;
    					if (tmp==i) break;
    				}
    			}
    		}
    		for (int j=n;l>0&&j>0;j--) 
    		{
    			if (a[j].p!=1&&!vis[j])
    			{
    				vis[j]=true;
    				s+=a[j].c;
    				l--;
    			}
    		}
    		if (l<=0) ans=min(ans,s);
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:

    80老婆如何制服老公的
    男人三件事
    抄袭了一篇散文,很适合现在的我.
    讲个小笑话
    博客的性别???测试下!!!
    十八禁 大全 [转载]
    [转载]男人你没房没车,我凭什么嫁给你!
    电脑维修 小产业高利润
    一美女莫名晕倒 被七男强行拖入森林
  • 原文地址:https://www.cnblogs.com/fmj123/p/14274676.html
Copyright © 2011-2022 走看看