Codeforces Round 893 (Div. 2)
B
题意:
有 n 个椅子,每个椅子编号为 1 - n, 其中有 m 个椅子上坐着一个卖饼的人,你需要从 1 走到 n,当你满足下面三个条件之一时你就要吃一块饼:
- 你在一号点时要吃一块饼
- 你距离上一次吃饼已经走过了 d 个椅子,那么你需要吃一块
- 当前椅子有一个卖饼人你需要吃一块
你现在可以移除一个卖饼人,问你最少要吃多少饼,有多少种方案?(每个点位,最多吃一个,不重复计算)
思路:
先把一个人都不移的情况下要吃多少饼,然后枚举一下删除各个点的比一下大小
inline void solve()
{
int n, m, d; cin >> n >> m >> d;
std::vector<int> s(m + 2);
for (int i = 1; i <= m; i++) cin >> s[i];
s[0] = 1, s[m + 1] = n + 1; // 因为一号点必吃一块,所以假设那里有个卖饼的,因为需要判断最后一个卖饼人离 n 的距离,所以在 n + 1 也假设一个
int tot = 1;
for (int i = 1; i <= m + 1; i++)
{
tot += (s[i] - s[i - 1] - 1) / d; // 两次吃饼间隔 d 个椅子就吃一次
if (s[i] != 1 && s[i] != n + 1) tot++; // 碰见卖饼人也要吃一个
}
int ans = inf, num = 0;
for (int i = 1; i <= m; i++)
{
int t = tot;
t -= (s[i] - s[i - 1] - 1) / d + (s[i + 1] - s[i] - 1) / d; // 删除s[i], 把他的贡献也删掉
if (s[i] != 1) t -= 1;
t += (s[i + 1] - s[i - 1] - 1) / d; // 删除之后间隔变大了,重新加上间隔吃饼数
if (t < ans)
{
ans = t;
num = 1;
}
else if (ans == t) num++;
}
cout << ans << ' ' << num << endl;
}

浙公网安备 33010602011771号