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; } |