D. Binary String To Subsequences #贪心 #构造

题目链接

题意

给定一个\(01\)串\(s\),完全分割成若干子序列(注意,不要混淆子串与子序列的概念),其中的子序列不包含两个相邻的\(0\)或\(1\)\((eg:"0101", "1010")\)。对\(s\)按这样的分割方式,最少能分出多少串子序列?同时,还要求输出\(s\)串中每一字符所在的分割出的子序列编号

分析

参考了官方题解的思路,我们可以定义两个数组为\(now0\)和\(now1\),\(now0\)存下了当前以0为结尾的所有10子序列,\(now1\)反之。

假定我们遇到\(str[i]\)为'\(0\)',为了使分割的子序列数量越少越好,当然是希望能够将这个字符'0'接入之前已创建好的子序列中,因此先检查\(now1\)是否存在以\(1\)结尾的10子序列。

如果存在,我们就接入(注意,接入后,该子序列的末尾是'0'了,因而需要在\(now0\)数组留下标记);如果不存在,我们只能从\(now0\)中创建一个新编号,注意这个编号是基于所有子序列的数量的。

#include <string>
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long ll;
int main(){
int q; scanf("%d", &q);
while(q--){
vector<int> ans;
vector<int> now1, now0;
int n; scanf("%d", &n);
string str; cin >> str;
//利用vector模拟过程,便于查看当前集合的元素个数,及增加/修改元素
for (int i = 0; i < n; i++){
int newkey = now0.size() + now1.size();//newkey用于统计最新子序列编号(从0开始)
if(str[i] == '0'){
if(now1.empty()){ //暂无最新的01串,只能构建以0为开头的新子序列
now0.push_back(newkey);
} //新子串+1
else{ //当前存在可接入的01串,为该串的尾部放置合适位置
newkey = now1.back(); //注意获取最新01串的编号
now0.push_back(newkey); //第newkey串结尾改为0
now1.pop_back(); //第newkey串结尾不再是1
}
}
else {
if(now0.empty()){ //暂无最新的10串
now1.push_back(newkey);
}
else{
newkey = now0.back();
now1.push_back(newkey);
now0.pop_back();
}
}
ans.push_back(newkey);
}
printf("%d\n", (int)(now1.size() + now0.size()));
for (int i = 0; i < n; i++){
printf("%d%c", ans[i] + 1, (i == n - 1) ? '\n' : ' ');
}
}
}

其实\(for\)循环内部不需要分出两个大\(if\)判断,可以定义\(now[2][...]\)然后通过\(now[!newkey]\)进行一系列操作即可

E1. Weights Division #贪心 #大顶堆

题目链接

题意

给定每条边带一定权值的有根树。你可以将任意一条边的权值减少一半,即\(w_i:=wi/2\)(向下取整),每一次对某一边权值减少一半记为一次操作。定义树的总重量:根节点到所有叶子路径权值之和。现给定\(S\),需要你用最少的操作次数使得树的总重量不超过\(S\)。

分析

根节点到达某一叶子的路径,与 根节点到达另一叶子的路径,很有可能发生部分重合。而题干中不遗漏路径中所有经过边的权值,所以我们需要提前将任何边的经过次数\(num\)统计下来。

我们很容易往贪心的方向考虑。贪心什么?我最初贪心,是将当前所有边中,出现次数\(\times\)边权得到的加权最大的边挑出来并进行修改。然而,这样不准确,比如{\(w_1=5, num_1=4\)}与{\(w_2=2, num_2=10\)},他们总加权相等,但由于边权值缩小是向下取整,5缩小一半对总权重的影响比2缩小一半更大。从这里我们可以发现,贪心的目标应该是选择缩小对树重量的影响最大的边即缩小前与缩小后之差最大。

#include <string>
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 5;
int H[MAXN], tot = 0;
ll s = 0, n, cursum = 0;
typedef struct Edge {
int to, nextNbr, num; ll w; //num记录该边的经过次数
bool operator < (const struct Edge& x) const {
return num * (w - w / 2) < x.num * (x.w - x.w / 2);
} //对总权重影响最大的,优先取出
}Edge;
Edge E[MAXN * 2];
priority_queue<Edge> myque;
void addEdge(int u, int v, ll w) {
tot++;
E[tot].to = v; E[tot].w = w; E[tot].nextNbr = H[u]; E[tot].num = 1;
H[u] = tot;
}
void Init() {
for (int i = 1; i <= n; i++) H[i] = -1;
tot = 0; cursum = 0;
while (!myque.empty()) myque.pop();
}
int dfs(int now, int pre) {
int cnt = 0; //cnt记录从now(除了叶节点)出发,它的出边的经过次数
bool f = false;
for (int i = H[now]; i >= 0; i = E[i].nextNbr) {
if (E[i].to != pre) { //保证不回退
E[i].num = dfs(E[i].to, now); //回溯返回该边的经过次数
cnt += E[i].num;
myque.push(E[i]);
cursum += (ll)E[i].num * E[i].w; //累加当前树的总权重
f = true;
}
}
return f ? cnt : 1; //如果是叶子节点即返回1,否则返回给上一条边的经过次数
}
int main() {
int q; scanf("%d", &q);
while (q--) {
scanf("%lld%lld", &n, &s); Init();
for (int i = 1; i <= n-1; i++) {
int u, v; ll w;
scanf("%d%d%lld", &u, &v, &w);
addEdge(u, v, w); addEdge(v, u, w);
}
dfs(1, 1); //对每一条边的出现次数及所有边的总权重作统计
ll ans = 0;
while (cursum > s) {
Edge tmp = myque.top(); myque.pop(); cursum -= tmp.w * tmp.num;
tmp.w = (ll)(tmp.w / 2); //该边权值
cursum += tmp.w * tmp.num; myque.push(tmp);
ans++;
}
printf("%lld\n", ans);
}
return 0;
}

Codeforces Round #661 (Div. 3) D、E1 题解的更多相关文章

  1. Codeforces Round #612 (Div. 2) 前四题题解

    这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...

  2. Codeforces Round #198 (Div. 2)A,B题解

    Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahu ...

  3. Codeforces Round #672 (Div. 2) A - C1题解

    [Codeforces Round #672 (Div. 2) A - C1 ] 题目链接# A. Cubes Sorting 思路: " If Wheatley needs more th ...

  4. Codeforces Round #614 (Div. 2) A-E简要题解

    链接:https://codeforces.com/contest/1293 A. ConneR and the A.R.C. Markland-N 题意:略 思路:上下枚举1000次扫一遍,比较一下 ...

  5. Codeforces Round #610 (Div. 2) A-E简要题解

    contest链接: https://codeforces.com/contest/1282 A. Temporarily unavailable 题意: 给一个区间L,R通有网络,有个点x,在x+r ...

  6. Codeforces Round #611 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1283 A. Minutes Before the New Year 题意:给一个当前时间,输出离第二天差多少分钟 ...

  7. Codeforces Round #499 (Div. 2) D. Rocket题解

    题目: http://codeforces.com/contest/1011/problem/D This is an interactive problem. Natasha is going to ...

  8. Codeforces Round #499 (Div. 2) C Fly题解

    题目 http://codeforces.com/contest/1011/problem/C Natasha is going to fly on a rocket to Mars and retu ...

  9. Codeforces Round #198 (Div. 2)C,D题解

    接着是C,D的题解 C. Tourist Problem Iahub is a big fan of tourists. He wants to become a tourist himself, s ...

随机推荐

  1. MySQL全面瓦解3:数据类型介绍与分析

    概述 MySQL支持很多数据类型,以便我们能在复杂的业务场景中支持各种各样的数据格式,存储适当的数据内容.我们在设计数据库时,正确的使用数据库类型对整个数据库的整洁和高效,会有很大的帮助. 目前常用的 ...

  2. Setuptools 【Python工具包详解】

    什么是setuptools setuptools是Python distutils增强版的集合,它可以帮助我们更简单的创建和分发Python包,尤其是拥有依赖关系的.用户在使用setuptools创建 ...

  3. 修改Anaconda中Jupyter Notebook默认工作路径

    修改Anaconda中Jupyter Notebook默认工作路径 1.打开 Anaconda Prompt 2.输入命令 jupyter notebook --generate-config 这个命 ...

  4. PageHelper使用步骤

    一.导入jar包(maven构建导入坐标) <dependency> <groupId>com.github.pagehelper</groupId> <ar ...

  5. Bootstrap 实现图片翻滚

    今天给大家带来的是Bootstrap 实现的图片翻滚 效果图如下 点击左右箭头可以实现向左向右转动,这个功能在Bootstrap 官网和菜鸟教程上都有讲解,有点bootstrap基础的都能看明白 ,这 ...

  6. Centos7安 装python3+Selenium+chrome+chromedriver

    Centos7安装python3+Selenium+chrome+chromedriver详细python2和python3共存,Selenium错误的处理更新Centos源 wget -O /etc ...

  7. delphi key解密转c# 解决string 不可变长度问题

    遇见问题: delphi的解密需要在c#里面实现 方法一:delphi编写delphi dll组件,c#里面调用 方法二:c#重写delphi的代码进行解析 方法一: delphi部分代码: libr ...

  8. k8s event监控利器kube-eventer对接企微告警

    背景 监控是保障系统稳定性的重要组成部分,在Kubernetes开源生态中,资源类的监控工具与组件监控百花齐放. cAdvisor:kubelet内置的cAdvisor,监控容器资源,如容器cpu.内 ...

  9. Spider--补充--jsonpath的使用

    # 知识点参见:https://blog.csdn.net/muzico425/article/details/102763176 # 示例:爬取示例网站的首页的评论: # 解析得到的字符串r.tex ...

  10. SpringBoot第十集:i18n与Webjars的应用(2020最新最易懂)

    SpringBoot第十集:i18n与Webjars的应用(2020最新最易懂) 一,页面国际化 i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符 ...