-
题目:
最近,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;
}