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)的更多相关文章

  1. Codeforces Round #380(div 2)

    A. 题意:给你一串字符串(<=100),将ogo ogogo ogogogo ogogogogo……这种全部缩成***,输出缩后的字符串 分析:第一遍扫对于那些go的位置,记录下next[i] ...

  2. 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,到每 ...

  3. codeforces Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)// 二分的题目硬生生想出来ON的算法

    A. Road to Cinema 很明显满足二分性质的题目. 题意:某人在起点处,到终点的距离为s. 汽车租赁公司提供n中车型,每种车型有属性ci(租车费用),vi(油箱容量). 车子有两种前进方式 ...

  4. Codeforces Round #380 (Div. 2) 总结分享

    B. Spotlights 题意 有n×m个格子的矩形舞台,每个格子里面可以安排一个演员或聚光灯,聚光灯仅可照射一个方向(俯视,上下左右).若聚光灯能照到演员,则称为"good positi ...

  5. Codeforces Round #380 (Div. 2) 解题报告

    第一次全程参加的CF比赛(虽然过了D题之后就开始干别的去了),人生第一次codeforces上分--(或许之前的比赛如果都参加全程也不会那么惨吧),终于回到了specialist的行列,感动~.虽然最 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. Swift 之 函数与闭包的应用实例

    http://www.cocoachina.com/swift/20160106/14862.html 今天的博客算是比较基础的,还是那句话,基础这东西在什么时候都是最重要的.说到函数,只要是写过程序 ...

  2. 2018-3-4-dotnet-设计规范-·-结构体定义

    title author date CreateTime categories dotnet 设计规范 · 结构体定义 lindexi 2018-03-04 17:48:44 +0800 2018-2 ...

  3. $.inArray()方法

    $.inArray() 函数用于在数组中查找指定值,并返回它的索引值(如果没有找到,则返回-1) 提示:源数组不会受到影响,过滤结果只反映在返回的结果数组中. 语法 $.inArray( value, ...

  4. MAC使用技巧之苹果电脑抓图截屏方法

    用苹果电脑自带的截图功能的快捷键:command+shift+3 三个键按下则抓取/截取全屏 command+shift+4 然后用鼠标框选则抓取该区域的截图 command+shift+4 然后按空 ...

  5. 报错OPTION SQL_SELECT_LIMIT=

    org.quartz.JobPersistenceException: Couldn't acquire next trigger: You have an error in your SQL syn ...

  6. python 同名变量引用

  7. 从url输入网址后发生什么

    从url输入网址后发生什么

  8. [React Native]获取网络状态

    使用React Native,可以使用NetInfo API获取手机当前的各个网络状态. componentWillMount() { NetInfo.fetch().done((status)=&g ...

  9. 国内 PHP Composer 镜像列表(2019-07-07)

    目录 国内 PHP Composer 镜像列表 Composer 是什么? 镜像列表 配置镜像 本文历史 参考 国内 PHP Composer 镜像列表 Composer 是什么? Composer ...

  10. 【数据库】sql2008卸载和默认实例的删除 标签: 数据库 2014-11-16 15:15 5878人阅读 评论(30)

    在安装sql2008的时候,会碰到这一步,要求创建实例,可以选择默认实例和命名实例,如果是第一次安装的话,可以选择默认实例,但是如果是第二次甚至更多次安装的 话,很多时候会出现不能用默认实例,只能自己 ...