Southern and Volga Russia Qualifier 2019-2020(A Yellow Cards(贪心))

Southern and Volga Russia Qualifier 2019-2020(A Yellow Cards(贪心))_第1张图片Southern and Volga Russia Qualifier 2019-2020(A Yellow Cards(贪心))_第2张图片
题意:两个队,然后给出需要罚下1队的一个人员和2队的一个人员各自的最少黄牌数目(就是第一队如果有一个人拿了k1张黄牌,那么就出局,第二个队如果有一个任拿了k2张黄牌,那么就出局);
现在给你了 黄牌在场上出现的次数(注意:题目上说了一张黄牌只能用一次);
问最少罚下的人数和最多罚下的人数;
这个就很明显了呗;
如果n>=a1k1+a1k2,这里a1k1+a2k2表示如果全部罚下,那么需要的总黄牌数目;如果n都大于等于它了,那么肯定全部罚下了呗,所以Min==Max;
如果nk1+a2k2,那么我怎么计算最小的罚下场的人数呢?
其实读懂第一个案例就明白了;
比如第一个案例:
第一个队有两个人,如果在第一队的每个人接受4张黄牌,那么就把8次黄牌用完了,所以就不会产生罚下人数了;
所以这就给了我一个思路:
不管是一队还是二队,如果每个人都差一张牌罚下的话,是不是就是求最小罚下人数的最优解呢?
想一想就可以理解了;
如果算最大罚下人数,就很简单了直接和min(k1,k2)求解就行;
AC代码:

#include 
using namespace std;
typedef long long ll;
int main()
{
   int a1,a2,k1,k2,n;
   int Min1=0,Max1=0;
   scanf("%d%d%d%d%d",&a1,&a2,&k1,&k2,&n);
   if(n>=a1*k1+a2*k2){
      printf("%d %d\n",a1+a2,a1+a2);return 0;
   }
   int t=n;
   t-=a1*k1-a1+a2*k2-a2;//这里就是  每个人都差一张被罚下
   if(t<=0)Min1=0;//如果剩余黄牌数目为<=0,那么说明一个人也不会被罚下
   else Min1+=t;//没多一张就会有一个人被罚下
   if(k1>k2){//这里就是来求最大被罚下的人数的,肯定要把罚下一个人需要的少的票拿出来用涩,这样才能使得罚下的人数最大
       int tt=min(n/k2,a2);//看看罚下的人数和a2原来的人数  是多了还是少了,取最少的一个
       n-=tt*k2;//剩余票数
       Max1+=tt+min(n/k1,a1);
   }else{//同理理解
        int tt=min(n/k1,a1);
       n-=tt*k1;
       Max1+=tt+min(n/k2,a2);
   }
   printf("%d %d\n",Min1,Max1);
    return 0;
}

你可能感兴趣的:(贪心算法)