Codeforces Round #574(Div.2)

A - Drinks Choosing(贪心)

题意:有n个学生,k种饮料,每个学生需要一种饮料,有n/2向上取整组饮料,每组饮料有两个同种饮料,求得到满足的学生的最多个数。

思路:a_{i}种饮料需要几个,b[a_{i}]/2可以取几组两个饮料都被喝掉的。b[a_{i}]是偶数时可以被处理完,是奇数的时候,选择这种饮料的人会剩1个,如果总组数减去用掉还大于0,就可以用来来满足剩下的。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int a[1005];
int b[1005];
int main()
{
    int n,k,cnt;
    cin>>n>>k;
    memset(b,0,sizeof(b));
    if(n%2==0)
    {
        cnt=n/2;
    }
    else
    {
        cnt=(n+1)/2;
    }
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[a[i]]++;
    }
    int ans=0;
    for(int i=1;i<=k;i++)
    {
        if(b[i]!=0)
        {
            ans+=(b[i]/2)*2;
            b[i]=b[i]-(b[i]/2)*2;
        }
    }
    int res=0;
     for(int i=1;i<=k;i++)
    {
        if(b[i]!=0)
        {
           res++;
        }
    }
    int p=cnt-ans/2;
    if(p>0&&res>0)
    {
        ans=min(n,ans+min(p,res));
    }
    cout<<ans<<endl;
}

B - Sport Mafia(数学)

题意:

有一个盒子,有n个操作,每个操作只能执行两个动作:

1.放入糖果,第一次放一个,第二次放两个,第三次放三个。。。
2.每次取操作都只取出一个糖果

执行n个操作和n个操作后盒子里剩余的糖果个数k。问执行了多少次取操作?

思路:

设放入x次,则取n-x次。

x+\frac{x*(x-1)}{2}-(n-x)==k
                    //-n+x==k
       4*x+ x*(x-1) ==2*(k+n)
       x^2+3*x==2*(k+n);

 已知等式右边的值,枚举x,使得左右两边相等跳出。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n,k;
    cin>>n>>k;
    ll p=2*(k+n),x,y;
    for(ll i=1;i*i<p;i++)
    {
        y=i*i+3*i;
        if(y==p)
        {
            x=i;
            break;
        }
    }
    ll ans=n-x;
    if(n-x<0)
      ans=0;
    cout<<ans<<endl;
       // x+x*(x-1)/2-(n-x)==k
                    //-n+x==k
        //4*x+ x*(x-1) ==2*(k+n)
        //x^2+3*x==2*(k+n);

}

C - Basketball Exercise(简单DP)

题意:现在有2n个人排成两排,每 n个人排成一排,每个人有一个身高,你要选人出来组成一个篮球队,要求选出来的人身高和最大。选人的时候同一排不能选连续的两个人,并且只能从左往右开始选择。

思路:

状态转移方程:

dp[0][j]=max(dp[1][j-1]+a[0][j],dp[0][j-1]);

dp[1][j]=max(dp[0][j-1]+a[1][j],dp[1][j-1]);

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx=1e5+10;
ll a[3][maxx];
ll dp[3][maxx];
int main()
{
  int n;
  cin>>n;
memset(dp,0,sizeof(dp));
  for(int i=0;i<2;i++)
  {
      for(int j=1;j<=n;j++)
      {
          cin>>a[i][j];
      }
  }
  dp[0][1]=a[0][1];
  dp[1][1]=a[1][1];


      for(int j=2;j<=n;j++)
      {
           dp[0][j]=max(dp[1][j-1]+a[0][j],dp[0][j-1]);
           dp[1][j]=max(dp[0][j-1]+a[1][j],dp[1][j-1]);
      }


  ll ans=-1;
  //for(int i=0;i<2;i++)
  //{
      //for(int j=1;j<=n;j++)
     // {
           ans=max(dp[0][n],dp[1][n]);
      //}
//
 // }
  cout<<ans<<endl;
  //0  ^1  1
  //1    0
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值