Codeforces Round #574 (Div. 2) a-c

这篇博客介绍了三道算法竞赛题目,分别是饮品选择问题、运动匪徒问题和篮球锻炼问题。在饮品选择问题中,解决策略是记录每种饮品的喜好人数,计算最多能分配的饮品数。运动匪徒问题通过二分查找法求解最大吃糖数。篮球锻炼问题使用动态规划找出最大化身高和的方案。
摘要由CSDN通过智能技术生成

A - Drinks Choosing

题目

题意
有n个学生 每个学生有自己喜欢的饮品 现在能买(n/2)向上取整份饮品 每份有两瓶 问最多有多少学生能得到自己喜欢的饮品

思路
记录每种饮品喜欢的人数 计算每种饮品凑满一份的份数
如果总份数<能买的份数 说明剩下的能买的份数只能满足那些凑不了一份的饮品种类 总份数*2+能买的-总份数
如果总份数>=能买的份数 也只能买能买的份数

代码

#include<iostream>
#include<map>

using namespace std;

int n,k,te;
map<int,int> mp;
map<int,int>::iterator it;

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=0;i<n;i++)
    {
        cin>>te;
        mp[te]++;
    }
    int ans=0;
    int tot=(n+1)/2;
    for(it=mp.begin();it!=mp.end();it++)
    {
        ans+=it->second/2;
    }
    if(ans<tot)
        ans=tot+ans;
    else
        ans=tot*2;
    cout<<ans<<endl;
    return 0;
}

B - Sport Mafia

题目

题意
盒子每次有两种选择
1.当盒子不为空可以取一个盒子里面的糖吃
2.放入比上次放入数量多一个的数量的糖
给你操作的次数n和最后盒子剩的糖数k 问最多吃几颗糖

思路
设放入的次数为a 吃掉的次数为b 有方程组
a+b=n
(1+a)a/2-b=k
联立得 (a
a+a)/2-(n-a)=k
通过二分模拟放入的次数a 来求吃掉的次数

代码

#include<iostream>
#include<map>

typedef long long ll;
using namespace std;

ll n,k,te;

bool erfen(ll mid)
{
    return (mid*mid+3*mid)/2-n<k;
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    ll l=0,r=n;
    while(l<=r)
    {
        ll mid=(l+r)/2;
        if(erfen(mid))
        {
            l=mid+1;
        }
        else
        {
            r=mid-1;
        }
    }
    cout<<n-l<<endl;
    return 0;
}

C - Basketball Exercise

题目

题意
2排人的身高 从左到右选 同一个序号只能出现一次 且两次连续选择不能选同一排 问选中的人最高的身高和是多少

思路
dp思路
dp[i][0]表示当前第一排选
dp[i][1]表示当前第二排选
dp[i][2]表示当前不选
每个点不断保存到达当前点的最大值 这样局部最优 到达整体最优

代码

#include<iostream>
#include<algorithm>

#define N 100005

typedef long long ll;
using namespace std;

ll n,k,te,a[N],b[N],dp[N][3];


int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i = 1; i<=n; i++)cin>>a[i];
    for(int i = 1; i<=n; i++)cin>>b[i];
    for(int i = 1; i <= n; i++) {
        dp[i][0] = max(dp[i-1][1], dp[i-1][2]) + a[i];
        dp[i][1] = max(dp[i-1][0], dp[i-1][2]) + b[i];
        dp[i][2] = max(dp[i-1][0], max(dp[i-1][1], dp[i-1][2]));
    }
    cout<< max(dp[n][0], max(dp[n][1], dp[n][2]))<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值