Codeforces Round #407 (Div. 2)

来源:互联网 发布:最火的网络用语 编辑:程序博客网 时间:2024/06/06 20:06
这次做了2题。A和C。弱鸡rating终于上1400了。

B题看描述觉得大概是数学题,所以连看都没看。

做了A题后,大概15min后发现我居然跑了600ms,觉得终测一定会TLE,所以重新做了。

看到BC过的人很少,没信心,直接LOCK了A去hack。

看到一个可以hack,但说我数据太大,提交不上去(我并不知道可以提交文件)所以没hack。

以后不这样来了,努力做题才是正事啊...(hack浪费了我40min)

C题看了下样例,发现都是从最大数字遍历到最小数字,猜可能是贪心,所以乱写了一个交上去WA了。

不过就因为写的过程中突然想起这是个求最大子段和的DP,赶紧改了再交,又WA。

很快发现是第二次DP没有初始化,改一下就上去就A了。

 

 

 A - Anastasia and pebbles 【贪心】

题意:我有两个篮子,一个篮子最多能装k个鹅卵石,且只能装一种鹅卵石。给你N种鹅卵石的个数,问你最少需要几天才能把全部鹅卵石装回家。

做法:贪心。一种鹅卵石 x 个,如果 x % k == 0,那么需要 x / k 个篮子,否则的话需要 x / k + 1个篮子才能装完,累计篮子数 ans 。每天有两个篮子,所以总共需要 (ans + 1) / 2个篮子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
int a[100100];
int main() {
    int n, k, x;
    scanf("%d%d", &n, &k);
    LL ans = 0;
    for(int i = 0; i < n; i++) {
        scanf("%d", &x);
        ans += x / k;    //需要 x/k 个篮子
        if(x % k) ans++; //如果还有剩余,拿酒还需要多一个篮子
    }
   cout << (ans + 1 >> 1) << endl;  //每天有两个篮子,所以总共需要 ans+1>>1 天
}

 

C - Functions again 【dp】

题意:

给你N个数(a[1]....a[n]),任意取 L, R使得上式得出最大值

做法:首先求递推公式b[i] = abs(a[i] - a[i+1])。然后求一正一负,或者一负一正的最大子段和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
int a[100100];
int b[100100];
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", a+i);
    }
    for(int i = 1; i < n; i++) {
        b[i] = abs(a[i] - a[i+1]);
    }
    LL sum = 0, summ = 0;  //分别统计正数和负数的最大子段和
    LL ans = -1;
    for(int i = 1; i < n; i++) {  //dp
        int temp = b[i];
        if( i % 2 == 0) temp = -temp; //一正一负
        summ += temp;
        sum += temp;
        ans = max(ans, sum);
        ans = max(ans, -summ);
        if(sum < 0) sum = 0;
        if(summ > 0) summ = 0;
    }
    cout << ans << endl;
}