codeforce 380(div.2)
A B 略
C:二分,贪心
设d(i, v)为 剩余油量为v时,车开距离i 所需要的最小时间,使用线性规划不难算出:
if v < i return INF; //无法到达
if v > 2*i return i;
if i <= v <= 2*i return LL(3)*i - v; 那么一辆车开到终点的最短时间等于 ∑d(g[i]-g[i-1], v)
这样只需要二分能开到终点的最小油量,取其中价格最低的即是答案
代码如下:
1 #include <cstdio>
2 #include <algorithm>
3 #include <cstring>
4
5 using namespace std;
6 #define INF 9999999999LL
7 const int maxn = 2e5 + 10;
8 int n, k, s, t;
9 typedef long long LL ;
10 LL cal(LL i, LL v) {
11 if(v < i) return INF;
12 if(v > 2*i) return i;
13 return LL(3)*i - v;
14 }
15 int c[maxn], v[maxn];
16 int g[maxn];
17 bool judge(LL v) {
18 LL sum = 0;
19 for(int i = 1; i <= k+1; i++) {
20 sum += cal(g[i]-g[i-1], v);
21 if(sum > t) return false;
22 }
23 return true;
24 }
25 int main() {
26 scanf("%d%d%d%d", &n, &k, &s, &t);
27 for(int i = 0; i < n; i++) {
28 scanf("%d%d", &c[i], &v[i]);
29 }
30 g[0] = 0;
31 for(int i = 1; i <= k; i++) {
32 scanf("%d", &g[i]);
33 }
34 g[k+1] = s;
35 sort(g, g+k+2);
36 LL L = 0, R = INF;
37 while(L < R) {
38 LL M = L + (R-L)/2;
39 if(judge(M)) R = M;
40 else L = M+1;
41 }
42 // printf("R = %d\n", R);
43 int ans = 1000000010;
44 for(int i = 0; i < n; i++) {
45 if(v[i] >= R) ans = min(ans, c[i]);
46 }
47 if(ans < 1000000010) printf("%d\n", ans);
48 else puts("-1");
49 }
D: 一道堪比A、B的水题,按顺序输出剩下的可以放船的位置直到不能装下所有船为止
1 #include <cstdio>
2 #include <cstring>
3 #include <utility>
4 #include <vector>
5 using namespace std;
6 const int maxn = 2e5 + 10;
7
8 int n, a, b, k;
9 char s[maxn];
10 vector<pair<int, int> > vec;
11 vector<int> ans;
12 int main() {
13 scanf("%d%d%d%d%s", &n, &a, &b, &k, s);
14 int cnt = 0;
15 for(int i = 0; i < n; ) {
16 int j = i+1;
17 if(s[i] == '0') {
18 while(s[j] == '0') j++;
19 if(j-i >= b){
20 vec.push_back(make_pair(i, j));
21 cnt += (j-i)/b;
22 }
23 }
24 i = j;
25 }
26 int k = cnt - a + 1;
27 printf("%d\n", k);
28 for(int i = 0;k && i < vec.size(); i++) {
29 int l = vec[i].first;
30 int r = vec[i].second;
31 int j = l + b - 1;
32 while(k && j < r) {
33 ans.push_back(j);
34 j += b;
35 k--;
36 }
37 }
38 printf("%d", ans[0]+1);
39 for(int i = 1; i < ans.size(); i++) printf(" %d", ans[i]+1);
40 printf("\n");
41 }
E:贪心,数状数组维护前缀和
分析题意我们可以发现,由于一个下级只能有一个直接上级,一个上级可以有多个直接从属,比如
5 1
0 1 1 1 1
最小出错数为0;
我们以num[i+1]表示有i个上级的人数 (i+1是为了方便写树状数组),用c[i+1] 来记录上级数为i的情况是否缺少,
c[i+1] = 0 表示 有i个上级的人数不为0,c[i+1] = 1 有i个上级的人数为0,即没有上级数为i的人
用数状数组维护 上级数小于 i 的情况中缺少的总个数。
比如 0 1 1 3 5, 上级数为i之前缺一个上级数为2的情况 ,所以get(3) = 1, 上级数为5之前缺少2 和 4 的情况, 所以get(5) = 2;
设错误人数为cnt,初始为0,用一个队列维护最大位置前缺少的位置
然后从上级数最多的情况开始考虑,
考虑上级数 为 i时,
if get(i) = 0 , print cnt //这时所有的上级数已经连续, 此时cnt就是答案
else {
将上级数为i的人一个一个依次填充到之前缺失的位置(相应上级数值),直到num[i] = 0 或者 缺失的位置被填满
注意:比最大上级数还要大的位置不需要填,容易出错
}
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 2e5 + ; int n, s;
int a[maxn];
int c[maxn];
int d[maxn];
int num[maxn];
void add(int x, int v) {
while(x < maxn) {
d[x] += v;
x += x&-x;
}
}
int get(int x) {
int ans = ;
while(x) {
ans += d[x];
x -= x&-x;
}
return ans;
}
queue<int> Q;
int main(){
scanf("%d%d", &n, &s);
int cnt = ;
int start = ;
for(int i = ; i <= n; i++) c[i] = ;
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
if(i == s && a[i] != ){
cnt++;
} else if(i != s && a[i] == ) {
cnt++;
} else {
num[a[i]+]++;
c[a[i]+] = ;
start = max(start,a[i]+);
}
}
for(int i = ; i <= start; i++) if(c[i] == ) {
Q.push(i);
}
int k = cnt;
while(k && !Q.empty()) {
int i = Q.front();
Q.pop();
k--;
c[i] = ;
num[i]++;
}
for(int i = ; i <= n; i++) add(i, c[i]);
for(int i = start; i > ; i--) {
int temp = get(i);
if(temp) {
int &k = num[i];
while(k && !Q.empty()) {
int u = Q.front();
Q.pop();
if(u >= i) break;
k--;
c[u] = ;
add(u, -);
num[u]++;
cnt++;
}
}
else {
break;
}
}
printf("%d\n", cnt);
}
F: 容易想到DP, 设d(i, j, k)为当前 Igor 先手时的状态,然后记忆化搜索,但是很不幸这样会爆内存 - -||
由于k的值不断增大,经简单计算k最大为64,并且Igor拿去的数量与zhenya拿去的数量之差不超过 64, i <= n/2 ,
这样我们可以设 d(i, r, k) ,r 为 zhenya比Igor多拿的数量+70(差值可能为负)
maxi = 2100, maxr = 140, maxk = 70
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std;
const int maxn = ;
#define INF 1000000007
#define S(i, j) (sum[j] - sum[i-1]) int sum[maxn];
int n; int d[][][];
int vis[][][];
int dp(int i, int r, int k) {
int j = n - r - (i-) + ;
//printf("%d %d %d\n", i, j, k);
if(i + k - > j) return ;
if(vis[i][r][k]) return d[i][r][k];
vis[i][r][k] = ;
int &ans = d[i][r][k];
ans = -INF;
int temp = S(i, i+k-);
int temp2;
if(j-k+ > i+k-) {
temp2 = -S(j-k+, j) + dp(i+k, n-(j-k)-(i+k-)+, k);
if(j-k > i+k-) {
temp2 = min(temp2, -S(j-k, j) + dp(i+k, n-(j-k-)-(i+k-)+, k+));
ans = max(ans, temp+temp2);
}
else ans = max(ans, temp+temp2);
}
else ans = max(ans, temp); if(i + k > j) return ans;
temp = S(i, i+k);
if(j-k > i+k) {
temp2 = - S(j-k, j) + dp(i+k+, n-(j-k-)-(i+k+-)+, k+);
if(j-k- > i+k) {
temp2 = min(temp2, -S(j-k-, j) + dp(i+k+, n-(j-k-)-(i+k+-)+, k+));
ans = max(ans, temp+temp2);
}
else ans = max(ans, temp+temp2);
}
else ans = max(ans, temp); return ans;
}
int main() { scanf("%d", &n);
sum[] = ;
for(int i = ; i <= n; i++) {
int a;
scanf("%d", &a);
sum[i] = sum[i-] + a;
}
int ans;
ans = dp(, , );
printf("%d\n", ans);
return ;
}
codeforce 380(div.2)的更多相关文章
- Codeforces Round #380(div 2)
A. 题意:给你一串字符串(<=100),将ogo ogogo ogogogo ogogogogo……这种全部缩成***,输出缩后的字符串 分析:第一遍扫对于那些go的位置,记录下next[i] ...
- Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)
http://codeforces.com/contest/737 A: 题目大意: 有n辆车,每辆车有一个价钱ci和油箱容量vi.在x轴上,起点为0,终点为s,中途有k个加油站,坐标分别是pi,到每 ...
- codeforces Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)// 二分的题目硬生生想出来ON的算法
A. Road to Cinema 很明显满足二分性质的题目. 题意:某人在起点处,到终点的距离为s. 汽车租赁公司提供n中车型,每种车型有属性ci(租车费用),vi(油箱容量). 车子有两种前进方式 ...
- Codeforces Round #380 (Div. 2) 总结分享
B. Spotlights 题意 有n×m个格子的矩形舞台,每个格子里面可以安排一个演员或聚光灯,聚光灯仅可照射一个方向(俯视,上下左右).若聚光灯能照到演员,则称为"good positi ...
- Codeforces Round #380 (Div. 2) 解题报告
第一次全程参加的CF比赛(虽然过了D题之后就开始干别的去了),人生第一次codeforces上分--(或许之前的比赛如果都参加全程也不会那么惨吧),终于回到了specialist的行列,感动~.虽然最 ...
- Codeforce#331 (Div. 2) A. Wilbur and Swimming Pool(谨以此题来纪念我的愚蠢)
C time limit per test 1 second memory limit per test 256 megabytes input standard input output stand ...
- Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2) E. Subordinates 贪心
E. Subordinates time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2) D. Sea Battle 模拟
D. Sea Battle time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2)C. Road to Cinema 二分
C. Road to Cinema time limit per test 1 second memory limit per test 256 megabytes input standard in ...
随机推荐
- VBA 生成带时间戳的随机数字
Function GenPasswd(length, level) Dim allstr, substr, passwd As String allstr = "0123456789abcd ...
- Notepad++ ssh NppFTP链接linux
Notepad++是一套非常有特色的自由软件的纯文字编辑器,有完整的中文化接口及支持多国语言编写的功能.现在用Notepad++来远程编辑Linux系统文本文件. Notepad++ 1.Linux操 ...
- 小爬爬5:重点回顾&&移动端数据爬取1
1. ()什么是selenium - 基于浏览器自动化的一个模块 ()在爬虫中为什么使用selenium及其和爬虫之间的关联 - 可以便捷的获取动态加载的数据 - 实现模拟登陆 ()列举常见的sele ...
- xib搭建scrollView无法滑动的问题
最近给xib中的scrollView添加contentView的时候,view的约束总是参照莫名其妙的东西,不是frameLayout就是safeArea 因为之前都是默认以superView为参照系 ...
- Java练习 SDUT-4303_简单的复数运算(类和对象)
简单的复数运算(类和对象) Time Limit: 2000 ms Memory Limit: 65536 KiB Problem Description 设计一个类Complex,用于封装对复数的下 ...
- Java练习 SDUT-2733_小鑫の日常系列故事(二)——石头剪子布
小鑫の日常系列故事(二)--石头剪子布 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 小鑫在上幼儿园的时候,喜欢跟小伙 ...
- HDU 1081 To The Max【dp,思维】
HDU 1081 题意:给定二维矩阵,求数组的子矩阵的元素和最大是多少. 题解:这个相当于求最大连续子序列和的加强版,把一维变成了二维. 先看看一维怎么办的: int getsum() { ; int ...
- Python数据集变量及相关含义
- ROS报错:IOError:[Errno 13]permission denied: /home/neousys/.ros/roscore-11311.pid"
在安装ROS后启动ROS,输入:roscore 时报错: 这个问题是由于该路径下ros文件权限造成的. 输入以下命令修改权限: sudo chmod -R ~/.ros/ 修改完成后再次输入rosco ...
- Android GDI 图形渲染
发布于2011-07-26 导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Andro ...