Codeforces Round #407 (Div. 2)
这次做了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; } |