update
This commit is contained in:
parent
011d911279
commit
124a4c7794
@ -1,3 +1,78 @@
|
||||
int main(){
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
using ll = long long;
|
||||
|
||||
int main() {
|
||||
ll n, p, q, x, y;
|
||||
cin >> n >> p >> q >> x >> y;
|
||||
string s;
|
||||
cin >> s;
|
||||
|
||||
ll all = 0;
|
||||
for (char c : s) {
|
||||
if (c == '+') all++;
|
||||
else all--;
|
||||
}
|
||||
ll d = q - p;
|
||||
ll dt = d - all;
|
||||
ll m = abs(dt) / 2;
|
||||
|
||||
ll ans = 1e18;
|
||||
vector<int> h(n + 2, 0);
|
||||
|
||||
for (int k = 0; k < n; k++) {
|
||||
if (dt >= 0) {
|
||||
ll now = p;
|
||||
ll f = 0;
|
||||
ll minv = p;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
int idx = n - k + i - 1;
|
||||
if (idx >= n) idx -= n;
|
||||
char c = s[idx];
|
||||
if (c == '+') {
|
||||
now++;
|
||||
} else {
|
||||
now--;
|
||||
f++;
|
||||
}
|
||||
ll ci = min(m, f);
|
||||
ll v = now + 2 * ci;
|
||||
if (v < minv) minv = v;
|
||||
}
|
||||
if (minv >= 0) {
|
||||
ll cost = 1LL * k * y + 1LL * m * x;
|
||||
if (cost < ans) ans = cost;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i <= n + 1; i++) h[i] = 0;
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
int idx = n - k + i;
|
||||
if (idx >= n) idx -= n;
|
||||
h[i] = h[i + 1] + (s[idx] == '+' ? 1 : 0);
|
||||
}
|
||||
ll now = p;
|
||||
ll minv = now - 2 * m + 2 * min(m, (ll)h[0]);
|
||||
for (int i = 1; i <= n; i++) {
|
||||
int idx = n - k + i - 1;
|
||||
if (idx >= n) idx -= n;
|
||||
if (s[idx] == '+') {
|
||||
now++;
|
||||
} else {
|
||||
now--;
|
||||
}
|
||||
ll v = now - 2 * m + 2 * min(m, (ll)h[i]);
|
||||
if (v < minv) minv = v;
|
||||
}
|
||||
if (minv >= 0) {
|
||||
ll cost = 1LL * k * y + 1LL * m * x;
|
||||
if (cost < ans) ans = cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
104
src/7/20/T371062.md
Normal file
104
src/7/20/T371062.md
Normal file
@ -0,0 +1,104 @@
|
||||
为了解决这个问题,我们需要修改一个记账单字符串,使其满足两个条件:账户在任意时刻不出现负数,且最终余额为指定值。记账单由 '+' 和 '-' 组成,分别表示存入和取出1元钱。初始余额为 p,最终余额需为 q。允许的操作包括取反某一位(耗时 x)和循环右移(耗时 y),目标是找到最小耗时。
|
||||
|
||||
### 方法思路
|
||||
1. **问题分析**:记账单长度为 n,每个字符为 '+' 或 '-'。初始余额 p,最终余额 q。总净变化量('+' 数减 '-' 数)必须等于 q - p。若当前总净变化量 D0 不等于 q - p,则需修改字符,每次修改(取反)会使总净变化量增加或减少 2。
|
||||
2. **循环移位处理**:通过循环移位 k 次,将字符串后 k 个字符移到前面。枚举所有可能的 k(0 到 n-1),对每个 k 生成新字符串。
|
||||
3. **字符修改**:
|
||||
- 若 Δ = (q - p) - D0 ≥ 0,需将 m = Δ / 2 个 '-' 改为 '+'。
|
||||
- 若 Δ < 0,需将 m = |Δ| / 2 个 '+' 改为 '-'。
|
||||
4. **非负条件检查**:对每个移位后的字符串,检查修改后任意时刻余额非负:
|
||||
- Δ ≥ 0 时,优先修改靠前的 '-',计算修改后的最小余额。
|
||||
- Δ < 0 时,优先修改靠后的 '+',计算修改后的最小余额。
|
||||
5. **耗时计算**:对每个有效 k,计算总耗时(k*y + m*x),并取最小值。
|
||||
|
||||
### 解决代码
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
long long n, p, q, x, y;
|
||||
cin >> n >> p >> q >> x >> y;
|
||||
string s;
|
||||
cin >> s;
|
||||
|
||||
long long D0 = 0;
|
||||
for (char c : s) {
|
||||
if (c == '+') D0++;
|
||||
else D0--;
|
||||
}
|
||||
long long d = q - p;
|
||||
long long delta = d - D0;
|
||||
long long m_val = abs(delta) / 2;
|
||||
|
||||
long long ans = 1e18;
|
||||
vector<int> h_arr(n + 2, 0);
|
||||
|
||||
for (int k = 0; k < n; k++) {
|
||||
if (delta >= 0) {
|
||||
long long current = p;
|
||||
long long f = 0;
|
||||
long long min_value = p;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
int index_s = n - k + i - 1;
|
||||
if (index_s >= n) index_s -= n;
|
||||
char c_char = s[index_s];
|
||||
if (c_char == '+') {
|
||||
current++;
|
||||
} else {
|
||||
current--;
|
||||
f++;
|
||||
}
|
||||
long long c_i = min(m_val, f);
|
||||
long long value = current + 2 * c_i;
|
||||
if (value < min_value) min_value = value;
|
||||
}
|
||||
if (min_value >= 0) {
|
||||
long long cost = 1LL * k * y + 1LL * m_val * x;
|
||||
if (cost < ans) ans = cost;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i <= n + 1; i++) h_arr[i] = 0;
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
int index_s = n - k + i;
|
||||
if (index_s >= n) index_s -= n;
|
||||
h_arr[i] = h_arr[i + 1] + (s[index_s] == '+' ? 1 : 0);
|
||||
}
|
||||
long long current = p;
|
||||
long long min_value = current - 2 * m_val + 2 * min(m_val, (long long)h_arr[0]);
|
||||
for (int i = 1; i <= n; i++) {
|
||||
int index_s = n - k + i - 1;
|
||||
if (index_s >= n) index_s -= n;
|
||||
if (s[index_s] == '+') {
|
||||
current++;
|
||||
} else {
|
||||
current--;
|
||||
}
|
||||
long long value = current - 2 * m_val + 2 * min(m_val, (long long)h_arr[i]);
|
||||
if (value < min_value) min_value = value;
|
||||
}
|
||||
if (min_value >= 0) {
|
||||
long long cost = 1LL * k * y + 1LL * m_val * x;
|
||||
if (cost < ans) ans = cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 代码解释
|
||||
1. **输入处理**:读取记账单长度 n、初始余额 p、目标余额 q、操作耗时 x 和 y,以及记账单字符串 s。
|
||||
2. **总净变化量计算**:遍历字符串,计算初始总净变化量 D0('+' 数减 '-' 数)。
|
||||
3. **计算 Δ 和 m**:Δ = (q - p) - D0,若 Δ 非负则 m = Δ / 2(需修改 m 个 '-' 为 '+'),否则 m = |Δ| / 2(需修改 m 个 '+' 为 '-')。
|
||||
4. **枚举循环移位次数 k**:对每个 k 生成移位后的字符串,检查修改后是否满足非负条件:
|
||||
- **Δ ≥ 0 时**:遍历字符串,计算修改后的最小余额,检查是否非负。
|
||||
- **Δ < 0 时**:预处理后缀 '+' 数,计算修改后的最小余额,检查是否非负。
|
||||
5. **计算最小耗时**:对满足条件的 k,计算总耗时(移位耗时 k*y + 修改耗时 m*x),并更新最小值。
|
||||
6. **输出结果**:输出最小耗时。
|
||||
|
||||
此方法通过枚举所有可能的循环移位,并高效检查修改后的有效性,确保在较大数据规模下(n ≤ 9000)也能在合理时间内求解。
|
1
src/7/20/book1.ans
Normal file
1
src/7/20/book1.ans
Normal file
@ -0,0 +1 @@
|
||||
3
|
2
src/7/20/book1.in
Normal file
2
src/7/20/book1.in
Normal file
@ -0,0 +1,2 @@
|
||||
9 2 3 2 1
|
||||
---++++++
|
1
src/7/20/book2.ans
Normal file
1
src/7/20/book2.ans
Normal file
@ -0,0 +1 @@
|
||||
4
|
2
src/7/20/book2.in
Normal file
2
src/7/20/book2.in
Normal file
@ -0,0 +1,2 @@
|
||||
10 2 4 5 2
|
||||
----++++++
|
1
src/7/20/book3.ans
Normal file
1
src/7/20/book3.ans
Normal file
@ -0,0 +1 @@
|
||||
81100
|
2
src/7/20/book3.in
Normal file
2
src/7/20/book3.in
Normal file
File diff suppressed because one or more lines are too long
1
src/7/20/book4.ans
Normal file
1
src/7/20/book4.ans
Normal file
@ -0,0 +1 @@
|
||||
280572552
|
2
src/7/20/book4.in
Normal file
2
src/7/20/book4.in
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user