1676:手机游戏题目描述明明的手机上有这样一个游戏,一排$n$个怪物,每一个怪物的血量是$m_i$。如今明明能够射出$k$个伤害均为$p$的火球,当某个火球射到第$i$个怪物,除了这个怪物会掉血$p$之外,它左边的第$j$个怪物($j≤i$),也会遭到$max(0,p-(i-j)^2)$的溅射伤害。当某个怪物的血量为负的时候,它就死了,但它的尸体依然存在,即其余怪物不会由于它死而改变位置。ios 明明想用这$k$个火球消灭掉全部的怪物,但他同时但愿每一个火球的伤害$p$能尽量的小,这样他才能完美过关。优化 全部数均为整数。spa 输入第一行两个数$n,k$。code 第二行$n$个数$m_1,m_2,…,m_n$表示每一个怪物的生命值。blog 输出一行一个整数表示最小的符合要求的$p$值。游戏 输入样例3 1 1 4 5 输出样例6 提示数据规模对于30%的数据,$n≤500$。string 对于100%的数据,$1≤n≤50000,1≤k≤100000,1≤m_i≤10^9$。io 思路很简单的一道常规二分, 代码#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int N = 5e4 + 12; int num[N]; ll offset[N]; //怪物受到的伤害 int n, k; inline bool check(ll p) { int cnt = 0; memset(offset, 0, sizeof(offset)); for (int i = n; i >= 1; i--) { while (offset[i] <= num[i]) { offset[i] += p; cnt++; if (cnt > k) return false; for (ll j = 1; p - j * j > 0 && i - j >= 1; j++) { offset[i - j] += p - j * j; } } } return true; } int main() { scanf(" %d %d", &n, &k); for (int i = 1; i <= n; i++) scanf(" %d", &num[i]); ll l = 1, r = 1e18; while (l < r) { ll mid = l + r >> 1; if (check(mid)) r = mid; else l = mid + 1; } printf("%d", r); return 0; } |