cf1945D 插队的最小花费
排队时前面有n个人,现在想通过插队来排进队伍前m,每次插队时可以选择前面的某个人x,与他互换位置,需要支付a[x]的费用给x,并且还要支付给中间每个人b[i]的费用。现在给定a[i]和b[i],求最小花费。
1<=m<=n<=2e5; 1<=a[i],b[i]<=1e9
分析:对于中间的某个人,要么经过他,要么跨过他,记dp[i][0]表示插队到位置i并且跨过他的最小花费,dp[i][1]表示插队到位置i并且经过他的最小花费,从后往前递推即可。
#include <bits/stdc++.h> using i64 = long long; const i64 inf = 1E16; const i64 N = 200005; i64 n, m, a[N], b[N], dp[N][2]; void solve() { std::cin >> n >> m; for (int i = 1; i <= n; i++) { std::cin >> a[i]; } for (int i = 1; i <= n; i++) { std::cin >> b[i]; } dp[n+1][0] = dp[n+1][1] = 0; for (int i = n; i >= 1; i--) { dp[i][0] = b[i] + std::min(dp[i+1][0], dp[i+1][1]); dp[i][1] = a[i] + std::min(dp[i+1][0], dp[i+1][1]); } i64 ans = inf; for (int i = 1; i <= m; i++) { ans = std::min(ans, dp[i][1]); } std::cout << ans << "\n"; } int main() { std::cin.tie(0)->sync_with_stdio(0); int t = 1; std::cin >> t; while (t--) solve(); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步