VK Cup 2018 Round 2 div2 C, D 题解 【思维题】
2018-03-26 11:51
696 查看
传送门
C: 给定n个严格递增的数, 要从中选择三个数, 再满足下标i< j < k, 且a[k] - a[i] <= U, 的两个限制下,问可以使这个a[k]-a[j]/a[k]-a[i]最大是多少.
思路:就是一道很简单的水题,只不过要进行一定的小推导, 首先我们要知道的是如果确定了i, k, 那么很明显j = i + 1; 因为这样才能使a[j] 最小, 即分子a[k]-a[j]越大, 所以我们现在应该解决如何确定i, k那么我们再次通过一些推导如果i, j确定, 那么k一定越大越好, 即如果X > Y , 那么一定有 X-a[j]/X-a[i] > Y-a[j]/Y-a[i], 又因为那个限制条件, 所以我们可以转换一下那个式子a[k] <= a[i] + U, 所以我们枚举i, 然后通过二分查找k, 取尽量大的k, 然后取max即可.
AC Code
D: 题意有一条河, 有一个人每天都会去看河的高度, 并且会在此时的高度画一条线, 这条线不会消失, 如果某天河的高度与前几天的相同, 那么他就不会画, 因为有已经有线了, 现在告诉你每天可以看到的线的数量, 问sigma(d[i]) 最小是多少, d[i] 定义为第i天在水下的线的数量.
思路: 我们定义t[i] = m[i] + d[i] + 1; 那么要最小化sigma(d[i])等价于最小化sigma(t[i]), 那么很明显我们只知道了m[i], 所以我们可以直接在m[i]上面进行加d[i], 然后问题就变成了在m[i]上如何加最少的d[i]使得t[i] 是非严格递增的数列,并且相邻之差要在1之间?, 所以我们直接贪心的做就好了, 首先从前往后扫, 如果m[i] > m[i+1] , 那么m[i+1] = m[i]; 那么怎么做第二个限制了, 我们就从后往前, 如果m[i] > m[i-1] + 1, 那么m[i-1] = m[i] - 1; 这样做的增量就是最小的sigma(d[i])了.
AC Code
C: 给定n个严格递增的数, 要从中选择三个数, 再满足下标i< j < k, 且a[k] - a[i] <= U, 的两个限制下,问可以使这个a[k]-a[j]/a[k]-a[i]最大是多少.
思路:就是一道很简单的水题,只不过要进行一定的小推导, 首先我们要知道的是如果确定了i, k, 那么很明显j = i + 1; 因为这样才能使a[j] 最小, 即分子a[k]-a[j]越大, 所以我们现在应该解决如何确定i, k那么我们再次通过一些推导如果i, j确定, 那么k一定越大越好, 即如果X > Y , 那么一定有 X-a[j]/X-a[i] > Y-a[j]/Y-a[i], 又因为那个限制条件, 所以我们可以转换一下那个式子a[k] <= a[i] + U, 所以我们枚举i, 然后通过二分查找k, 取尽量大的k, 然后取max即可.
AC Code
const int maxn = 1e5+5; int a[maxn]; void solve() { int n, u; while(~scanf("%d%d", &n, &u)) { for (int i = 1 ; i <= n ; i ++) { scanf("%d", a+i); } db ans = -1; int flag = 1; for (int i = 1 ; i <= n - 2; i ++) { int k = upper_bound(a+1, a+1+n, a[i]+u) - a; --k; if (k < i+2) continue; ans = max(ans, (1.0*a[k]-a[i+1])/(1.0*a[k]-a[i])); } if (ans == -1) cout << -1 << endl; else printf("%.9f\n", ans); } }
D: 题意有一条河, 有一个人每天都会去看河的高度, 并且会在此时的高度画一条线, 这条线不会消失, 如果某天河的高度与前几天的相同, 那么他就不会画, 因为有已经有线了, 现在告诉你每天可以看到的线的数量, 问sigma(d[i]) 最小是多少, d[i] 定义为第i天在水下的线的数量.
思路: 我们定义t[i] = m[i] + d[i] + 1; 那么要最小化sigma(d[i])等价于最小化sigma(t[i]), 那么很明显我们只知道了m[i], 所以我们可以直接在m[i]上面进行加d[i], 然后问题就变成了在m[i]上如何加最少的d[i]使得t[i] 是非严格递增的数列,并且相邻之差要在1之间?, 所以我们直接贪心的做就好了, 首先从前往后扫, 如果m[i] > m[i+1] , 那么m[i+1] = m[i]; 那么怎么做第二个限制了, 我们就从后往前, 如果m[i] > m[i-1] + 1, 那么m[i-1] = m[i] - 1; 这样做的增量就是最小的sigma(d[i])了.
AC Code
const int maxn = 1e5+5; int a[maxn]; void solve() { int n; while(~scanf("%d", &n)) { for (int i = 1 ; i <= n ; i ++) { scanf("%d", a+i); } ll ans = 0; for (int i = 1 ; i < n ; i ++) { if (a[i] > a[i+1]) { ans += a[i] - a[i+1]; a[i+1] = a[i]; } } for (int i = n ; i > 1 ; i --) { if (a[i] > a[i-1] + 1) { ans += a[i]-1 - a[i-1]; a[i-1] = a[i]-1; } } printf("%lld\n", ans); } }
相关文章推荐
- VK Cup 2018 Round 2: A. Mystical Mosaic(思维)
- VK Cup 2018 Round 2: C. Riverside Curio(思维)
- VK Cup 2018 Round 2: D. Contact ATC(思维+树状数组)
- VK Cup 2018 Round 1 and CF Round #470 div2 C
- VK Cup 2016 - Round 1 (Div. 2 Edition) A Bear and Reverse Radewoosh
- Codeforces Round #272 (Div. 2) D. Dreamoon and Sets (思维 数学 规律)
- Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1) B. Primal Sport
- 【Codeforces Round 336 (Div 2) C】【贪心 DP思维】Chain Reaction 每个灯塔位置为a[]破坏b[]范围所有灯塔 设置一个灯塔使得最多灯塔被保留
- Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2) 总结
- VK Cup 2018 - Round 2 C - Riverside Curio 贪心
- Codeforces Round #400 (Div. 1 + Div. 2, combined)D. The Door Problem【2-sat Tarjan+思维建图】
- VK Cup 2016 - Round 1 (Div. 2 Edition) C. Bear and Forgotten Tree 3
- VK Cup 2016 - Round 1 (Div. 2 Edition)----D Bear and Polynomials 数论+二进制,很好的题!!!
- 【VK Cup 2016 - Round 1 (Div 2 Edition)C】【构造】Bear and Forgotten Tree 3 构造一棵树直径为d且点1的深度为h
- Codeforces Round #445 (Div. 1, based on Technocup 2018 Elimination Round 3) E. Mod Mod Mod
- 【模拟】 Codeforces Round #434 (Div. 1, based on Technocup 2018 Elimination Round 1) C. Tests Renumeration
- Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)(A.思维题,B.思维题)
- Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1) C. Producing Snow
- Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2) D. Something with XOR Queries
- Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination) A. Search for Pretty Integers