-
題目:
最近,H國正在建設一條信號傳輸通道,這條通道將會依次經過 n+2 個城市,它們恰好分布在 x- 數軸上。不妨分別編號為城市 0 到城市 n+1,那么城市 i 的坐標恰好為 i。
在這 n+2 個城市中,有且僅有城市 0 和城市 n+1 已有建設好的信號基站,你可以在城市 1∼n 中的若干個(或 0 個)城市中也建立信號基站以提高這條信號傳輸通道的質量,並收獲一定的民眾滿意度。具體地來說,如果選擇在城市 i 建造信號基站,那么可以收獲 ai的民眾滿意度。信號傳輸通道的優質指數被定義為該傳輸通道任意兩個相鄰基站的最小距離。
H國找到了國內頂尖的工程師,也就是你,來設計該條信號傳輸通道的建造方法,在收獲的總民眾滿意度不少於 W 的前提下,最大化該條信號傳輸通道的優質指數。
輸入格式:第一行包含兩個整數,分別表示 n,W(0 ≤ n ≤ 2 × 10^5, 0 ≤ W ≤ 1 * 10^18)
第二行包含 n 個整數,第 i 個整數表示 ai (0 ≤ ai ≤ 10^9)。輸出格式:輸出一行僅一個整數,表示建造的信號傳輸通道最大的優質指數。如果無解,輸出-1。
輸入:
11 12
1 2 1 2 6 2 1 2 1 2 1
輸出:
2 -
思路:二分枚舉任意兩基站最小距離,dp記錄最大滿意度進行與W比較即可。
-
解析:首先,我們二分枚舉任意兩個基站的最小距離x,用dp[i]記錄到第i個基站為止總民眾滿意度的最大值(在基站間距離最小為x條件下),這里需要特別注意第0個城市與第n+1個城市已經建有基站.
- dp[i] = dp[i-1]; //不在第i個城市建基站
- dp[i] = dp[i-x] + a[i](i - x >= 0 && i + x <= n + 1); //可以選擇在第i個城市建基站
- 比較兩者大小即可
- 然后最后判斷dp[n]與w的大小,若dp[n] >= w,說明相鄰基站最小距離可以擴大,否則相鄰基站最小距離需要縮小
- w為0的時候特判一下即可
-
代碼:
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
int n, flag = 0;
ll w, a[N], dp[N]; //dp(i):到第i個城市在任意兩個相鄰基站的最小距離x下的最大滿意度
int main()
{
cin >> n >> w;
for(int i = 1; i <= n; i++) cin >> a[i];
if(!w) //特判
{
cout << n + 1 << endl;
return 0;
}
int l = 0, r = N, x = 0;
while(l < r)
{
memset(dp, 0, sizeof dp);
x = (l + r + 1) / 2; //二分兩個相鄰基站的最小距離
dp[0] = 0;
for(int i = 1; i <= n; i++)
{
dp[i] = dp[i-1]; //不選擇第i個城市建基站
if(i - x >= 0 && i + x <= n + 1) //可選擇第i個城市建基站
dp[i] = max(dp[i], dp[i-x] + a[i]);
}
if(dp[n] >= w) //將相鄰基站最小距離擴大
{
l = x;
flag = 1;
}
else r = x - 1;
}
if(flag && l) cout << l << endl;
else cout << -1 << endl;
return 0;
}
