# NOIP算法总结——关于简单 线性动态规划

## 一、算法的选取，动态维护。

7
2 -4 3 -1 2 -4 3

4

### 说明

【数据规模与约定】

【洛谷1115】

#include <bits/stdc++.h>
using namespace std ;
int a[200010] ;
int main() {
int i, j, k, m, n ;
scanf ( "%d", &n ) ;
for ( i = 1 ; i <= n ; i ++ )
scanf ( "%d", a+i ) ;
int ans = -2147483647 ;
for ( i = 1 ; i <= n ; i ++ )
for ( j = i ; j <= n ; j ++ ) {
int sum = 0 ;
for ( k = i ; k <= j ; k ++ )
sum += a[k] ;
ans = max ( ans, sum ) ;
}
printf ( "%d\n", ans ) ;
return 0 ;
}

#include <bits/stdc++.h>
using namespace std ;
int a[200010] ;
int main() {
int i, j, k, m, n ;
scanf ( "%d", &n ) ;
for ( i = 1 ; i <= n ; i ++ ) {
scanf ( "%d", a+i ) ;
a[i] += a[i-1] ;
}
int ans = -2147483647 ;
for ( i = 1 ; i <= n ; i ++ )
for ( j = i ; j <= n ; j ++ ) {
int sum = 0 ;
sum = a[j] - a[i-1] ;
ans = max ( ans, sum ) ;
}
printf ( "%d\n", ans ) ;
return 0 ;
}

#include <bits/stdc++.h>
using namespace std ;
int a[200010] ;
int main() {
int i, j, k, m, n ;
scanf ( "%d", &n ) ;
for ( i = 1 ; i <= n ; i ++ ) {
scanf ( "%d", a+i ) ;
a[i] += a[i-1] ;
}
int ans = -2147483647, Min = 0 ;
for ( i = 1 ; i <= n ; i ++ ) {
ans = max ( ans, a[i] - Min ) ;
Min = min ( a[i], Min ) ;
}
printf ( "%d\n", ans ) ;
return 0 ;
}

## 二、前缀和的利用

#### 输入输出样例

4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1

##### 输出样例#1：

2

sum(i,j) 表示点(1,1)和点(i,j)围成矩形里元素的和。（如下图）

s=sum[x2][y2]sum[x2][y11]sum[x11][y2]+sum[x11][y11]

sum[i][j]=sum[i1][j]+sum[i][j1]sum[i1][j1]+a[i][j]

#include <bits/stdc++.h>
using namespace std ;
const int maxn = 110 ;
bool a[maxn][maxn] ; // 记录原始数组
int sum[maxn][maxn] ; // sum意义同上所述
int main() {
int i, j, k, m, n, l ;
scanf ( "%d%d", &n, &m ) ;
for ( i = 1 ; i <= n ; i ++ )
for ( j = 1 ; j <= m ; j ++ )
scanf ( "%d", &a[i][j] ) ;
for ( i = 1 ; i <= n ; i ++ )
for ( j = 1 ; j <= m ; j ++ )
sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + a[i][j] ; // 递推计算sum
int x2, y2, x1, y1 ;
int ans = -1000000000, L ; // 用于存储最大面积，答案边长
for ( x1 = 1 ; x1 <= n ; x1 ++ )
for ( y1 = 1 ; y1 <= m ; y1 ++ )
for ( l = 1 ; l+x1-1 <= n && l+y1-1 <= m ; l ++ ){
x2 = l+x1-1 ; y2 = l+y1-1 ;
int s = sum[x2][y2] - sum[x2][y1-1] - sum[x1-1][y2] + sum[x1-1][y1-1] ;
if ( s != l*l ) continue ;
if ( s > ans ) {
ans = s ;
L = l ;
}
}
printf ( "%d\n", L ) ;
return 0 ;
}

## 三、简单的递推。

#### 输入输出样例

10
2 3 5
2 3 5 6 7

##### 输出样例#1：

2

To Be Continue … …