|
|
|
@ -1,14 +1,12 @@
|
|
|
|
|
## 【前缀和与差分】题单
|
|
|
|
|
|
|
|
|
|
**[参考文献](https://blog.csdn.net/piqihaoshaonian/article/details/127515000)**
|
|
|
|
|
|
|
|
|
|
### 一、公式
|
|
|
|
|
#### 前缀和的公式
|
|
|
|
|
#### 前缀和公式
|
|
|
|
|
一维:$s[i] = a[i] + s[i-1]$
|
|
|
|
|
|
|
|
|
|
二维:$s[i][j] = a[i][j] + s[i-1] [j] + s[ i] [j-1] - s[i-1][j-1]$
|
|
|
|
|
|
|
|
|
|
#### 差分的公式
|
|
|
|
|
#### 差分公式
|
|
|
|
|
一维:$b[i] =s[i] - s[i-1]$
|
|
|
|
|
|
|
|
|
|
二维:$b[i] = s[i][j] - s[i-1][j]-s[i][j-1]+s[i-1][j-1]$
|
|
|
|
@ -16,13 +14,10 @@
|
|
|
|
|
### 二、题单
|
|
|
|
|
#### [$P1115$ 最大子段和](https://www.luogu.com.cn/problem/P1115)
|
|
|
|
|
|
|
|
|
|
**总结**
|
|
|
|
|
一维前缀和+思维
|
|
|
|
|
|
|
|
|
|
**分析**
|
|
|
|
|
先求每个位置的前缀和(某个区间求和前缀和可以说是最快的),然后去找该位置前前缀和的最小值,如果要求一段和最大,就要用这段和减去前面最小的值。
|
|
|
|
|
先求每个位置的前缀和,然后去找 **该位置前面** 前缀和的最小值,如果要求一段和最大,就要用这段和 **减去前面最小的值**。
|
|
|
|
|
|
|
|
|
|
**前缀和解法**
|
|
|
|
|
##### 一维前缀和解法
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
@ -46,7 +41,15 @@ int main() {
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
$DP$ 解法
|
|
|
|
|
##### $DP$ 解法
|
|
|
|
|
|
|
|
|
|
**状态定义**
|
|
|
|
|
$dp[i]$: 走完前$i$个数字,在此阶段中可以获取到的最大子段和。
|
|
|
|
|
|
|
|
|
|
**状态转移**
|
|
|
|
|
- 如果从前面的结果中借力划算,那就借力
|
|
|
|
|
- 如果借力不合适,那就自己单干
|
|
|
|
|
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|