Educational Codeforces Round 111 (Rated for Div. 2)

本文分享了作者在Codeforces Round #685 (Div. 2)比赛中的解题心得,详细解析了两道题目A-FindTheArray和B-MaximumCostDeletion的思路和解决方案。对于A题,通过贪心策略从1开始每次增加2,直到和大于给定数n,证明了这种方法能找到满足条件的最小元素集合。B题则讨论了如何以最大成本删除字符串中的字符,分析了根据b值正负确定最佳操作次数的方法。
摘要由CSDN通过智能技术生成

@[toc](Educational Codeforces Round 111 (Rated for Div. 2))

狂刷CF的时机到了,开干开干~~
2021/7/15,第1场,奥里给!!!

A-Find The Array

题目地址:A-Find The Array

题意:
给定一个s,问一个满足条件1的集合最小长度是多少
条件1:一个长度为n的集合,其中的元素要要么是1,要么是k,如果是k的话,说明集合中已经存在了k-1,k-2

解决:
最贪心的考虑,从1开始,每次增长2,直到和大于n结束,增长的次数就是我们的答案
证明:我们贪心的增长,增长的速度一定是最快的,如果正确答案是ans,那么按照最快的增长速度,所得的集合元素一定是最小的,所以实际元素个数n一定是<=ans的。
下面证明,一定可以通过不增加n的个数,将n个元素的元素和使之等于s。
因为我们按照最快的增长速度,当大于等于s的时候停止增长。所以,只会在最后一次出现大于s的情况,而最后一次出现的数是导致大于s的原因,最后一个数字过大了,那么将最后一个数分配给前面的数字就可以了。而分配的话,可以分配从1~1+2(n-1)中的任意一个。

#include <bits/stdc++.h>
using namespace std;
void work()
{
  int n; cin >> n;
  int cnt = 1;
  for (int i = 1; i <= n; i += 2)
  {
    if (n > i) n -= i, cnt ++;
    else break;
  }
  cout << cnt << endl;
}
int main()
{
  int T;
  cin >> T;
  while (T -- )
  {
    work();
  }
  return 0;
}

B-Maximum Cost Deletion

B-Maximum Cost Deletion

题目:
T组数据,T大小为2000.每组数据中,给定n,a,b。n大小为100,a和b是-100到100。
第二行是一个0、1串S。现在可以不断执行操作1,最终使的S串为空串。
操作1:可以选择长度为L的连续的相同字符消掉,然后将剩下的两段子串合并,子串可以为空串,同时得到得分a*L+b

解决:
我们尝试着将所有可能加在一起,发现,如果我们合并k次的话,我们得到了的结果为a * n + k * b
所以,不管我们怎么合并,an是不变的,改变的就是kb,也就是合并次数的不同,kb的值随之改变。
那么,如果b是大于0的,我们就做尽可能多的变换,最多就是每个字符都做操作1,那么结果就是a * n + b * n
如果b小于等于0,我们就做尽可能少的操作1,那么,我们计算一下,连续的1和0总共出现多少次。然后取最小的一次,在+1,+a
n

#include <bits/stdc++.h>
using namespace std;
void work()
{
  int n, a, b; cin >> n >> a >> b;
  int s0 = 0, s1 = 0;//记录连续0出现次数,连续1出现次数
  int last = -1;
  for (int i = 0; i < n; i ++ )
  {
    int x; scanf("%1d", &x);
    if (x)
    {
      if (last != x) s1 ++;
    }
    else
    {
      if (last != x) s0 ++;
    }
    last = x;
  }
  // cout << s0 << " " << s1 << endl;
  if (b > 0) cout << n * (a + b) << "\n";
  else cout << min(s0 + 1, s1 + 1) * b + n * a << "\n";
}
int main()
{
  int T; cin >> T;
  while (T -- )
  {
    work();
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值