• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yumiym765

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

D. Not Alone

D. Not Alone

Problem - D - Codeforces

处理一:\(b_i = b_{(i+m-2)\bmod m\;+1}\), 或 \(b_i = b_{i\bmod m\;+1}\)

​ 考虑将环分成多块处理,保证块长大于 \(1\)。

处理二:\(\sum_{i=1}^n |b_i - a_i|\)

​ 由于对于 \(a_i\),操作只有 \(+1\) 和 \(-1\),对于每个块,最小的操作数就是将其变成中位数(中位数定理)。

​ 那么划分成多块操作会超时,我们考虑会不会有更好的策略:

​ 观察一个块内有 \(4\) 个元素:可以拆成两个 \(2\) 个元素的块,这样总会使得结果变小。

​ 同理最终把块拆成 \(2\) 块和 \(3\) 块总会使得答案最好。

​ 如果长度为 \(2\) 和 \(3\),\(cost\) 就是最大值 \(-\) 最小值。

处理三:环

​ 将数组循环移位操作几次,然后在开头断开,断环成链进行计算。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1000000000000000005;

ll cost(ll x, ll y){
    return max(x, y) - min(x, y);
}
ll cost(ll x, ll y, ll z){
    return max({x, y, z}) - min({x, y, z});
}
void solve(){
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for(int i = 1;i <= n;i++){
        cin >> a[i];
    }
    auto f = [&]() -> ll{
        vector<ll> dp(n + 1, 0);
        dp[0] = 0;
        dp[1] = INF;
        for(int i = 2;i <= n;i++){
            dp[i] = dp[i - 2] + cost(a[i - 1], a[i]);
            if(i >= 3){
                dp[i] = min(dp[i], dp[i - 3] + cost(a[i - 2], a[i - 1], a[i]));
            }
        }
        return dp[n];
    };
    ll ans = INF;
    for(int cyc = 0; cyc < 4;cyc++){
        ans = min(ans, f());
        for(int i = 2;i <= n;i++){
            swap(a[i], a[i - 1]);
        }
    }
    cout << ans << "\n";
}

int main(){
    //ios::sync_with_stdio(false);
    //cin.tie(nullptr), cout.tie(nullptr);
    int T = 1;
    cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

posted on 2025-10-15 16:29  羊毛corn  阅读(3)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3