因为cf上一堆水题,每个单独开一篇博客感觉不太好,就直接放一起好了。

CF1096D Easy Problem

给定字符串,每个位置删除要代价。求最小代价使之不含子序列"hard"。

设f[i][f]表示前i个删到只匹配f位子序列的最小代价。转移看代码吧。O(n)

 #include <bits/stdc++.h>

 typedef long long LL;
const int N = ; int a[N];
LL f[N][];
char str[N]; int main() {
int n;
scanf("%d", &n);
scanf("%s", str + );
for(int i = ; i <= n; i++) scanf("%d", &a[i]); int tag = ;
for(int i = ; i <= n; i++) {
if(tag == && str[i] == 'h') tag++;
if(tag == && str[i] == 'a') tag++;
if(tag == && str[i] == 'r') tag++;
if(tag == && str[i] == 'd') tag++;
}
if(tag != ) {
printf("0\n");
return ;
} for(int i = ; i <= n; i++) {
f[i][] = f[i - ][] + a[i] * (str[i] == 'h');
f[i][] = f[i - ][] + a[i] * (str[i] == 'a');
f[i][] = f[i - ][] + a[i] * (str[i] == 'r');
f[i][] = f[i - ][] + a[i] * (str[i] == 'd');
if(str[i] == 'h') f[i][] = std::min(f[i][], f[i - ][]);
if(str[i] == 'a') f[i][] = std::min(f[i][], f[i - ][]);
if(str[i] == 'r') f[i][] = std::min(f[i][], f[i - ][]);
} LL ans = std::min(std::min(f[n][], f[n][]), std::min(f[n][], f[n][])); printf("%lld\n", ans);
return ;
}

AC代码

CF1036C Classy Numbers

问[l, r]之间有多少个数满足非0数码不超过三个。

裸数位DP......注意每次读完要把char数组清空...

 /**
* There is no end though there is a start in space. ---Infinity.
* It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
* Only the person who was wisdom can read the most foolish one from the history.
* The fish that lives in the sea doesn't know the world in the land.
* It also ruins and goes if they have wisdom.
* It is funnier that man exceeds the speed of light than fish start living in the land.
* It can be said that this is an final ultimatum from the god to the people who can fight.
*
* Steins;Gate
*/ #include <bits/stdc++.h> typedef long long LL;
const int N = ; LL f[N][][];
char str[N], str1[N], str2[N]; LL DFS(int k, int cnt, int z) {
if(cnt > ) return ;
if(!k) {
return ;
}
if(f[k][cnt][z] != -) {
return f[k][cnt][z];
}
LL ans = ;
if(cnt < ) {
for(int i = ; i <= ; i++) {
ans += DFS(k - , cnt + , );
}
}
ans += DFS(k - , cnt, z);
return f[k][cnt][z] = ans;
} LL DFS_2(int k, int cnt, int z) {
if(cnt > ) return ;
if(!k) return ;
int lm = str[k] - '';
//printf("k = %d cnt = %d z = %d lm = %d \n", k, cnt, z, lm);
LL ans = DFS_2(k - , cnt + (lm != ), z | (lm != ));
if(lm) {
ans += DFS(k - , cnt, z);
}
for(int i = ; i < lm; i++) {
ans += DFS(k - , cnt + , );
}
return ans;
}
/*
1
29000000000091 29000000000099 */
inline void dec(int &n) {
for(int i = ; i <= n; i++) {
if(str[i] != '') {
str[i]--;
break;
}
else str[i] = '';
}
if(str[n] == '') n--;
return;
} int main() {
memset(f, -, sizeof(f));
LL l, r;
int T;
scanf("%d", &T);
for(int i = ; i <= T; i++) {
scanf("%s%s", str1 + , str2 + );
int n = strlen(str2 + );
memcpy(str + , str2 + , sizeof(char) * n);
std::reverse(str + , str + n + ); /*for(int j = 1; j <= n; j++) {
putchar(str[j]);
}
puts("");*/ LL ans = DFS_2(n, , );
//printf("temp ans = %lld \n", ans);
memset(str2 + , , n * sizeof(char));
n = strlen(str1 + );
memcpy(str + , str1 + , n * sizeof(char));
std::reverse(str + , str + n + );
dec(n); /*for(int j = 1; j <= n; j++) {
putchar(str[j]);
}
puts("");*/ ans -= DFS_2(n, , );
printf("%lld\n", ans);
memset(str1 + , , n * sizeof(char));
} return ;
}

AC代码

CF1132C Painting the Fence

给定n个区间,选出n - 2个区间使它们覆盖的总长度最大。转为删去两个区间。

去重 + 排序。考虑到答案要么相邻要么不相邻,相邻的预处理前后缀覆盖总长之后直接枚举。

预处理出只删每个区间的时候的覆盖减少量为di。当不相邻的时候,考虑到减少总量就是他们两个的di之和。

于是枚举一个区间,拿一个数据结构维护[1, i - 2]之间的最小d值即可。

注意答案不能比总长度还优。复杂度O(nlogn) / O(n)

 /**
* There is no end though there is a start in space. ---Infinity.
* It has own power, it ruins, and it goes though there is a start also in the star. ---Finite.
* Only the person who was wisdom can read the most foolish one from the history.
* The fish that lives in the sea doesn't know the world in the land.
* It also ruins and goes if they have wisdom.
* It is funnier that man exceeds the speed of light than fish start living in the land.
* It can be said that this is an final ultimatum from the god to the people who can fight.
*
* Steins;Gate
*/ #include <bits/stdc++.h> const int N = ; struct Node {
int l, r;
inline bool operator < (const Node &w) const {
if(l != w.l) return l < w.l;
return r > w.r;
}
}node[N], stk[N]; int top; int n, m, sl[N], sr[N], del[N], pw[N], ST[N][]; namespace t1 {
int d[N];
inline void solve() {
for(int i = ; i <= n; i++) {
d[node[i].l]++;
d[node[i].r + ]--;
}
int ans = , now = ;
for(int i = ; i <= m; i++) {
now += d[i];
ans += (now > );
}
printf("%d\n", ans);
return;
}
} namespace t2 {
inline void solve() {
int ans = ;
for(int i = ; i <= n; i++) {
ans = std::max(ans, std::min(sl[i - ] + sr[i + ], sr[]));
}
printf("%d\n", ans);
return;
}
} inline void prework() {
for(int i = ; i <= n; i++) { /// get sl del
sl[i] = sl[i - ] + node[i].r - std::max(node[i].l, node[i - ].r + ) + ;
del[i] = std::min(node[i].r, node[i + ].l - ) - std::max(node[i].l, node[i - ].r + ) + ;
del[i] = std::max(del[i], );
}
for(int i = n; i >= ; i--) { /// get sr
sr[i] = sr[i + ] + std::min(node[i].r, node[i + ].l - ) - node[i].l + ;
}
return;
} inline void prework2() {
for(int i = ; i <= n; i++) {
pw[i] = pw[i >> ] + ;
}
for(int i = ; i <= n; i++) ST[i][] = del[i];
for(int j = ; j <= pw[n]; j++) {
for(int i = ; i + ( << j) - <= n; i++) {
ST[i][j] = std::min(ST[i][j - ], ST[i + ( << (j - ))][j - ]);
}
}
return;
} inline int getMin(int l, int r) {
if(l > r) return 0x3f3f3f3f;
int t = pw[r - l + ];
return std::min(ST[l][t], ST[r - ( << t) + ][t]);
} int main() {
scanf("%d%d", &m, &n);
for(int i = ; i <= n; i++) {
scanf("%d%d", &node[i].l, &node[i].r);
} std::sort(node + , node + n + );
int k = ;
for(int i = ; i <= n; i++) {
if(top && stk[top].r >= node[i].r) {
k--;
continue;
}
stk[++top] = node[i];
}
n = top;
memcpy(node + , stk + , n * sizeof(Node)); if(k <= ) {
t1::solve();
return ;
}
node[n + ].l = node[n + ].r = 0x3f3f3f3f;
prework(); if(k == ) {
t2::solve();
return ;
} /// solve int ans = ;
for(int i = ; i < n; i++) { /// choose i i + 1
ans = std::max(ans, std::min(sl[i - ] + sr[i + ], sr[]));
}
/// not neighbor prework2(); for(int i = ; i <= n; i++) {
ans = std::max(ans, sr[] - del[i] - getMin(, i - ));
}
printf("%d\n", ans);
return ;
}

AC代码

CF1132F Clear the String

给定字符串,一次可以删去连续的一段相同字符,问最少多少次删光。

有一个很直观的想法是f[l][r][k]表示把[l, r]删成k个str[l]的最小代价,发现不好O(1)转移...

然后又考虑f[l][r][k]表示[l, r]右端加上k个str[r]之后删去的最小代价,也不会转移...

尝试n2状态,发现这个k,完全没必要记具体个数,因为无论多少个都是一次删掉。

于是采用CF1025D的套路,fa[l][r]表示把[l, r]删成只剩str[l - 1]的最小代价,fb是str[r + 1],ans是删光的最小代价。

转移fa的时候考虑str[r]和str[l - 1]是否相同并以此转移。转移ans的时候选出一个位置,左边的fb + 右边的fa转移。

 #include <bits/stdc++.h>

 const int N = ;

 int fa[N][N], fb[N][N], ans[N][N];
char str[N]; inline void exmin(int &a, const int &b) {
if(a > b) a = b;
return;
} int main() {
memset(fa, 0x3f, sizeof(fa));
memset(fb, 0x3f, sizeof(fb));
memset(ans, 0x3f, sizeof(ans));
int n;
scanf("%d", &n);
scanf("%s", str + );
for(int i = ; i <= n; i++) {
fa[i][i] = (str[i] != str[i - ]);
fb[i][i] = (str[i] != str[i + ]);
ans[i][i] = ;
}
for(int len = ; len <= n; len++) {
for(int l = ; l + len - <= n; l++) {
int r = l + len - ;
/// fa[l][r] fb[l][r] ans[l][r]
if(str[r] == str[l - ]) {
exmin(fa[l][r], fa[l][r - ]);
}
else {
for(int k = l; k < r; k++) {
exmin(fa[l][r], fa[l][k] + ans[k + ][r]);
}
}
if(str[l] == str[r + ]) {
exmin(fb[l][r], fb[l + ][r]);
}
else {
for(int k = l; k < r; k++) {
exmin(fb[l][r], ans[l][k] + fb[k + ][r]);
}
}
for(int k = l + ; k < r; k++) {
exmin(ans[l][r], fb[l][k - ] + fa[k + ][r] + );
}
exmin(ans[l][r], fa[l + ][r] + );
exmin(ans[l][r], fb[l][r - ] + );
exmin(fa[l][r], ans[l][r]);
exmin(fb[l][r], ans[l][r]);
//printf("[%d %d] l = %d r = %d ans = %d \n", l, r, fa[l][r], fb[l][r], ans[l][r]);
}
}
printf("%d\n", ans[][n]);
return ;
}

AC代码

然而本题还有多种简单一点的方法......

就设f[l][r]表示把[l, r]删光的代价,考虑str[l]是如何被删的。显然要么是单独被删,要么是跟某些位置一起删。不妨设一起删的位置中第二个是k。

枚举这个k,于是答案就是f[l + 1][k - 1] + f[k][r]

 #include <bits/stdc++.h>

 const int N = ;

 int f[N][N];
char str[N]; inline void exmin(int &a, const int &b) {
if(a > b) a = b;
return;
} int main() {
memset(f, 0x3f, sizeof(f));
int n;
scanf("%d", &n);
scanf("%s", str + );
for(int i = ; i <= n; i++) {
f[i][i] = ;
}
for(int len = ; len <= n; len++) {
for(int l = ; l + len - <= n; l++) {
int r = l + len - ;
/// fa[l][r] fb[l][r] ans[l][r]
exmin(f[l][r], f[l + ][r] + );
if(str[l] == str[l + ]) {
exmin(f[l][r], f[l + ][r]);
}
for(int k = l + ; k <= r; k++) {
if(str[k] == str[l]) {
exmin(f[l][r], f[l + ][k - ] + f[k][r]);
}
}
}
}
printf("%d\n", f[][n]);
return ;
}

AC代码

CF1132D Stressful Training

题意:有n个笔记本,一开始有ai格电,每分钟消耗bi格电。你要买一个每分钟充x格点的插头,使得这些笔记本都能撑过k分钟。问x的最小值。

解:不难想到二分。然后check里每天挑最早没电的充电。如果直接用堆的话是nlog2n的,然而我卡过去了...

实际上我们可以考虑把这些笔记本按照没电天来分类,发现同类笔记本我们不需要知道它们的相对大小,于是直接vector。然后从前往后扫一遍,就能做到线性。

注意二分上界是1e12...

 #include <bits/stdc++.h>

 typedef long long LL;
const int N = ; inline char gc() {
static char buf[N], *p1(buf), *p2(buf);
if(p1 == p2) p2 = (p1 = buf) + fread(buf, , N, stdin);
return p1 == p2 ? EOF : *p1++;
} template <class T> inline void read(T &x) {
x = ;
register char c(gc());
bool f(false);
while(c < '' || c > '') {
if(c == '-') f = true;
c = gc();
}
while(c >= '' && c <= '') {
x = x * + c - ;
c = gc();
}
if(f) x = (~x) + ;
return;
} struct Node {
LL now, del;
double x;
Node(LL A = , LL B = ) {
now = A;
del = B;
x = (double)A / B;
}
inline bool operator < (const Node &w) const {
return x > w.x;
}
}node[N]; int n, k;
LL a[N], b[N];
std::priority_queue<Node> Q; inline bool check(LL x) {
while(Q.size()) Q.pop();
for(register int i = ; i <= n; i++) {
Q.push(node[i]);
}
for(register int i = ; i < k; i++) {
Node temp = Q.top();
Q.pop();
if(temp.now - temp.del * i < ) {
return false;
}
temp = Node(temp.now + x, temp.del);
Q.push(temp);
}
Node temp = Q.top();
if(temp.now - temp.del * k < ) {
return false;
}
return true;
} int main() { read(n); read(k);
k--;
for(register int i = ; i <= n; i++) {
read(a[i]);
}
for(register int i = ; i <= n; i++) {
read(b[i]);
}
for(register int i = ; i <= n; i++) {
if(b[i] * k <= a[i]) {
std::swap(a[i], a[n]);
std::swap(b[i], b[n]);
n--;
i--;
}
} if(!n) {
puts("");
return ;
} for(int i = ; i <= n; i++) {
node[i] = Node(a[i], b[i]);
}
std::sort(node + , node + n + ); LL l = , r = 2e12;
while(l < r) {
LL mid = (l + r) >> ;
if(check(mid)) {
r = mid;
}
else l = mid + ;
}
if(r == 2e12) puts("-1");
else {
printf("%lld\n", r);
}
return ;
}

AC代码

CF集萃1的更多相关文章

  1. CF集萃3

    CF1118F2 - Tree Cutting 题意:给你一棵树,每个点被染成了k种颜色之一或者没有颜色.你要切断恰k - 1条边使得不存在两个异色点在同一连通块内.求方案数. 解:对每颜色构建最小斯 ...

  2. CF集萃2

    CF1155D - Beautiful Array 题意:给你一个序列和x,你可以选择任意一个子串(可以为空)乘上x,使得得到的序列最大子串和最大.求这个最大值.30w,2s. 解:设fi,0/1/2 ...

  3. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  4. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  5. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  6. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  7. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

  8. CF memsql Start[c]UP 2.0 A

    CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...

  9. CF memsql Start[c]UP 2.0 B

    CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...

随机推荐

  1. Java8 Stream实例--统计出所有含‘张’字的人员的平均年龄

    package com.zhangxueliang.demo; import java.util.ArrayList; import java.util.List; import java.util. ...

  2. Day 5-3 多态与多态性

    多态与多态性 鸭子类型 多态与多态性 多态:一类事物有多种形态.比如,动物有多种形态,人,狗,猪,豹子.水也有多种形态,冰,雪,水蒸气. #多态:同一类事物的多种形态 import abc class ...

  3. 转《vue引入第三方js库》

    一.绝对路径直接引入,全局可用 二.绝对路径直接引入,配置后,import 引入后再使用 三.webpack中配置 alias,import 引入后再使用 四.webpack 中配置 plugins, ...

  4. bootStrap的使用

    1.首先要打开bootstrap的官网 点进去 2你会看到下面这样一个页面里面有很多组件 这里面的代码是实现组件功能的核心代码,还不能直接使用,要引入相关的js css 我们要在起步中下载相关的页面下 ...

  5. MySQL最大连接数设置

    在使用MySQL数据库的时候,经常会遇到这么一个问题,就是“Can not connect to MySQL server. Too many connections”-mysql 1040错误,这是 ...

  6. Python魔法方法(magic method)细解几个常用魔法方法(上)

    这里只分析几个可能会常用到的魔法方法,像__new__这种不常用的,用来做元类初始化的或者是__init__这种初始化使用的 每个人都会用的就不介绍了. 其实每个魔法方法都是在对内建方法的重写,和做像 ...

  7. linux查看端口是否开放

    在讨论这个问题前,我们先来了解一下物理端口.逻辑端口.端口号等计算机概念. 端口相关的概念: 在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型.物理端口指的是物理存在的端口,如ADSL M ...

  8. QTP自动化测试-笔记 注释、大小写

    1 rem 注释内容 2 ' 注释内容 3 快捷键注释-选择代码行-ctrl+M 4 ctrl+shift+同- 取消注释 大小写 qtp:对小写敏感:如果 变量.sheet页是用小写字母命名,则使用 ...

  9. vs code安装

    vs code是一款文本编辑器,开源,是前端界的vs,而Dreamweaver适合入门. user版本的一些系统分区文件夹无法创建,可能存在语言显示问题.一般用户建议使用system版. 下载链接:h ...

  10. 一、VS2017支持Github

    选择 工具-->扩展和更新,搜索GitHub,安装GitHub的VS插件 安装完插件,打开视图-->团队资源管理器,我们可以看到Git插件菜单.通过菜单我们可以新建Git存储库,可以提交修 ...