• [20191004机房测试] C++锦标赛


    有一个比赛已经有 n 个人参加,并且互相之间已经进行了比赛
    每一个人都有一个得分用于最后排名
    你作为第 n + 1 个参赛者,需要与之前的每一个人打一场比赛,初始得分为 0
    对于每场比赛,有两个人参加,不会存在平局,胜者得分增加 1,败者得分不变
    最后按照得分从高到低来排名,假设有人与你最终得分相同
    那么如果那个人曾经输给了你就会排在你后面,否则会排在你的前面
    如果你赢了某个人,就需要消耗相应的 RP 值
    现在你可以决定赢那些人,求最少需要消耗多少 RP 值才能到前k名
    

    50分做法:还是枚举二进制串……居然有50分

    100分做法:
    这个满分做法是真的玄学,我们需要分三种情况讨论来贪心求解:

    1. 如果一个人的胜场和自己相同或者刚好少1,不打就会被挤下去,打了就可以升一位
    2. 如果一个人的胜场比自己多,打不打都没什么差异……
    3. 如果一个人的胜场比自己少2或者更多,那就可以不用打了
      然后贪心就好

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 2505
    using namespace std;
    
    int T,n,k,gol,num;
    ll ans;
    bool used[maxn];
    
    struct People
    {
    	int p, e;
    }p[maxn];
    
    bool cmp1(People x, People y) {return x.p > y.p;}
    bool cmp2(People x, People y) {return x.e < y.e;}
    
    bool check()
    {
    	int res=0;
    	for(register int i=1;i<=n;++i)
    		if(p[i].p>n) res++;
    	return res>=k;
    }
    
    ll work1()
    {
    	ll ret=0;	
    	int cnt=gol,num1=0,num2=num;
    	for(register int i=1;i<=n;++i)
    	{
    		used[i]=0;
    		if(p[i].p==gol-1) ++num1; 
    	}
    	for(register int i=1;i<=n&&num2;++i)
    	{
    		if(p[i].p==gol)
    		{
    			ret=ret+p[i].e;	
    			used[i]=1;
    			--cnt;
    			--num2;
    		}
    	}
    	for(register int i=1;i<=n&&num1;++i)
    	{
    		if(!used[i]&&(p[i].p==gol||p[i].p==gol-1))
    		{
    			ret=ret+p[i].e;	
    			used[i]=1;
    			--cnt;
    			--num1;
    		}
    	}
    	for(register int i=1;i<=n&&cnt;++i)
    	{
    		if(!used[i])
    		{
    			ret=ret+p[i].e;
    			--cnt;
    		}
    	}
    	return ret;
    }
    
    ll work2()
    {
    	ll ret=0;
    	int num2=num,cnt=gol+1;
    	for(register int i=1;i<=n;++i) used[i]=0;
    	for(register int i=1;i<=n&&num2;++i)
    	{
    		if(p[i].p==gol||p[i].p==gol+1)
    		{
    			used[i]=1;
    			ret=ret+p[i].e;
    			--cnt;
    			--num2;
    		}
    	}
    	for(register int i=1;i<=n&&cnt;++i)
    	{
    		if(!used[i])
    		{
    			ret=ret+p[i].e;
    			--cnt;
    		}
    	}
    	return ret;
    }
    
    ll work3()
    {
    	ll ret=0;
    	for(register int i=1;i<=gol+2;++i)
    		ret=ret+p[i].e;
    	return ret;
    }
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    int main()
    {
    	freopen("tournament.in","r",stdin);
    	freopen("tournament.out","w",stdout);
    	read(T);
    	while(T--)
    	{
    		read(n);read(k);
    		for(register int i=1;i<=n;++i) scanf("%d%d",&p[i].p,&p[i].e);
    		if(k==n+1)
    		{
    			printf("0
    ");
    			continue;
    		}
    		if(check())
    		{
    			printf("-1
    ");
    			continue;
    		}
    		sort(p+1,p+n+1,cmp1);
    		gol=p[k].p;
    		num=1;
    		while(p[k+num].p==p[k].p&&k+num<=n)	++num;
    		sort(p+1,p+n+1,cmp2);
    		ans=min(work1(),min(work2(),work3()));
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    爬虫问题总结
    keras快速开始序贯(Sequential)模型
    参数估计回顾
    CSDN-markdown编辑器 字体颜色修改
    贝叶斯决策学习
    概率论中的基本公式
    VMware tools安装
    Python 常用技巧:库/模块的安装、查看和卸载
    Google 机器学习笔记一 Pandas简介
    支持向量机 数学推导 part3
  • 原文地址:https://www.cnblogs.com/tqr06/p/11622889.html
Copyright © 2020-2023  润新知