题意: 打 在 a i 处 , a i − 1 掉 一 滴 血 , a i 掉 两 滴 血 , a i + 1 掉 一 滴 血 。 {打在a_i处,a_{i-1}掉一滴血,a_i掉两滴血,a_{i+1}掉一滴血。}打在ai处,ai−1掉一滴血,ai掉两滴血,ai+1掉一滴血。 问打掉两块(<=0)所需最小的步数。
思路:
三种情况:
- 相邻:先打至齐平,在打单个。不过会有先到0的情况,取个min。
- 隔一位:打中间使左右同时-1。
- 数组最小的两位,单独打。
#include<iostream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<cmath>
#include<set>
#include<climits>
#include<map>
#include<cstring>
using i64 = int64_t;
using namespace std;
#define endl '\n'
//#define int i64
const int maxn = 1e6 + 10;
int a[maxn], n, ans = INT_MAX;
void solve()
{
cin >> n;
for(int i = 1;i <= n;i++)cin >> a[i];
for(int i = 1;i < n;i++)ans = min(ans,max(max((a[i] + 1) / 2, (a[i + 1] + 1) / 2), (a[i] + a[i + 1] + 2) / 3 ));//相邻 打法1 只打其中一个 打法2 交替打
for(int i = 2;i < n;i++)ans = min(ans,min(a[i + 1],a[i - 1]) + (abs(a[i + 1] - a[i -1 ]) + 1 )/ 2);// 间隔一位
sort(a + 1,a + 1 + n);
ans = min(ans,(a[1] + 1) / 2 + (a[2] + 1) / 2);//俩块单独打
cout << ans << endl;
}
int main()
{
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//cin >> T;
while(T--)
solve();
return 0;
}