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. 权值线段树&&可持久化线段树&&主席树

    权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...

  2. RestfulApi 学习笔记——简单介绍(一)

    前言 什么是restapi? 直接看:http://www.ruanyifeng.com/blog/2014/05/restful_api.html 阮一峰的blog,即可明白,下面是一些例子,增强理 ...

  3. python数据分析使用matplotlib绘图

    matplotlib绘图 关注公众号"轻松学编程"了解更多. Series和DataFrame都有一个用于生成各类图表的plot方法.默认情况下,它们所生成的是线形图 %matpl ...

  4. K8S的Kafka监控(Prometheus+Grafana)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. pip install kaggle 出现 【网络不可达】?

    解决办法: pip install kaggle -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

  6. 1.深入Istio:Sidecar自动注入如何实现的?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 这篇文章打算讲一下sidecar, ...

  7. react 实现组件嵌套以及子组件与父组件之间的通信

    当子组件触发onChange事件时,实际调用的是父组件中的handelSelect函数,通俗来说就是父组件通过属性handleSelect实现与子组件之间的通信. 父组件:SignupForm 子组件 ...

  8. leetcode131:letter-combinations-of-a-phone-number

    题目描述 给出一个仅包含数字的字符串,给出所有可能的字母组合. 数字到字母的映射方式如下:(就像电话上数字和字母的映射一样) Input:Digit string "23"Outp ...

  9. LR逻辑回归附代码

    参考https://zhuanlan.zhihu.com/p/74874291 import pandas as pdpd.set_option('display.max_columns', 500) ...

  10. impala-shell -o a.txt 查询中有中文时报错问题的处理

    当使用impala-shell -o a.txt进入impala-shell之后,查询报错: 报错情况: Query: select * from dim_sales_dept Unknown Exc ...