mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-08-21 18:52:07 +00:00
添加 T637677 问题的完整解决方案,包括输入处理、动态规划实现和输出逻辑
This commit is contained in:
parent
391e21c91d
commit
767c57290d
115
src/7/23/T637677d.cpp
Normal file
115
src/7/23/T637677d.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
solution of https://www.luogu.com.cn/problem/T637677
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
using ll = int64_t;
|
||||
|
||||
const ll f = 50000;
|
||||
const ll msize = 100001;
|
||||
const ll inf = 1000000;
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(0);
|
||||
|
||||
ll n, m;
|
||||
cin >> n >> m;
|
||||
vector<ll> d(n);
|
||||
long long T0 = 0;
|
||||
for (ll i = 0; i < n; i++) {
|
||||
ll a, b;
|
||||
cin >> a >> b;
|
||||
d[i] = a - b;
|
||||
T0 += d[i];
|
||||
}
|
||||
|
||||
vector<ll> dp0(msize, inf);
|
||||
vector<ll> dp1(msize, inf);
|
||||
|
||||
if (0 + f >= 0 && 0 + f < msize) {
|
||||
dp0[0 + f] = 0;
|
||||
}
|
||||
ll nx0 = d[0] + f;
|
||||
if (nx0 >= 0 && nx0 < msize) {
|
||||
dp1[nx0] = 1;
|
||||
}
|
||||
|
||||
for (ll i = 1; i < n; i++) {
|
||||
vector<ll> ndp0(msize, inf);
|
||||
vector<ll> ndp1(msize, inf);
|
||||
|
||||
for (ll x = 0; x < msize; x++) {
|
||||
ndp0[x] = min(dp0[x], dp1[x]);
|
||||
}
|
||||
|
||||
for (ll x = 0; x < msize; x++) {
|
||||
if (dp0[x] != inf) {
|
||||
ll nx = x + d[i];
|
||||
if (nx >= 0 && nx < msize) {
|
||||
if (dp0[x] + 1 < ndp1[nx]) {
|
||||
ndp1[nx] = dp0[x] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ll x = 0; x < msize; x++) {
|
||||
if (dp1[x] != inf) {
|
||||
ll nx = x + d[i];
|
||||
if (nx >= 0 && nx < msize) {
|
||||
if (dp1[x] < ndp1[nx]) {
|
||||
ndp1[nx] = dp1[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dp0 = move(ndp0);
|
||||
dp1 = move(ndp1);
|
||||
}
|
||||
|
||||
ll ans = inf;
|
||||
for (ll x = 0; x < msize; x++) {
|
||||
if (dp0[x] == inf && dp1[x] == inf) continue;
|
||||
long long xv = (long long)(x - f);
|
||||
if (abs(T0 - 2 * xv) <= m) {
|
||||
if (dp0[x] < ans) ans = dp0[x];
|
||||
if (dp1[x] < ans) ans = dp1[x];
|
||||
}
|
||||
}
|
||||
|
||||
if (ans == inf) {
|
||||
ans = n;
|
||||
}
|
||||
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
输入处理:读取骨牌数量n和目标值m,计算每个骨牌的差值d_i和初始总差T0。
|
||||
|
||||
初始化DP数组:dp0和dp1分别存储不在区间中和在区间中的状态,大小为100001(覆盖X的偏移范围)。
|
||||
|
||||
初始状态设置:第一个骨牌不翻转(X=0)或在区间中翻转(X=d[0])。
|
||||
|
||||
状态转移:遍历每个骨牌,更新状态:
|
||||
|
||||
新dp0:从上一状态的dp0或dp1不翻转当前骨牌转移而来。
|
||||
|
||||
新dp1:从dp0翻转当前骨牌(操作数+1)或从dp1翻转当前骨牌(操作数不变)转移而来。
|
||||
|
||||
结果检查:遍历所有可能的X值,检查是否满足|T0 - 2X| ≤ m,并记录最小操作次数。
|
||||
|
||||
输出:满足条件的最小操作次数,若无解则输出n(最坏情况)。
|
||||
|
||||
此方案通过动态规划高效求解最小操作次数,时间复杂度为O(n × range_size),其中range_size为100001,适用于给定约束。
|
||||
|
||||
*/
|
Loading…
Reference in New Issue
Block a user