在这里插入代码片
#### 前缀和
最近做题的时候经常看到前缀和,所以就系统的查了一下
一维前缀和
什么是前缀和?前缀和是一个数组的某项下标之前(包括此项元素)的所有数组元素的和。
设b[]为前缀和数组,a[]为原数组,根据这句话可以得到前缀和的定义式和递推式:
定义式 | 递推式 | |
---|---|---|
一维前缀和 | ||
for(int i = 1 ; i<=n ; i++ )
cin >>A[i] ;
for(int i = 1 ; i<=n ; i++ )
s[i] = s[i-1] + A[i] ;
正如上图,a[2]=1+2+3;
a[3]=1+2+3+4=a[2]+4;
a[4]=1+2+3+4+5=a[3]+5;
例题:
给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
请返回 nums 的动态和。
示例 1:
输入:nums = [1,2,3,4]
输出:[1,3,6,10]
解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。
示例 2:输入:nums = [1,1,1,1,1]
输出:[1,2,3,4,5]
解释:动态和计算过程为 [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1] 。
示例 3:输入:nums = [3,1,2,10,1]
输出:[3,4,6,16,17]
这是典型的前缀和案例,
这是我之前写的:
class Solution {
public int[] runningSum(int[] nums) {
int k=0;
for(int i=1;i<nums.length;i++)
{
nums[i]+=nums[i-1];
}
return nums; }
}
这样写非常暴力,本身没有错,但是如果数组很长,O(n2)容易超时,而且做了许多无用功,不属于优化之后的.
那么就要优化,下图:
class Solution {
public:
vector<int> runningSum(vector<int>& nums) {
for(int i=1;i<nums.size();i++)
{
nums[i]+=nums[i-1];
}
return nums;
}
};//减了一个for循环,O(n)
当然了,向以上这种题一看就能晓得使用前缀和会更好,那就看下面
因为上述讲的就是前缀和,所以这一个也应该用前缀和来做,但是如果这就是随机一道题,而且在前缀和不熟练的情况下,你未必真的会想到前缀和这个概念.所以还是多做题为好
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <cstdbool>
#include <string.h>
#include <math.h>
using namespace std;
int main()
{
int a[100005] = {0};
int b[100005] = {0};
int n;
cin >> n;
for (int i=1;i<=n;i++)
{
cin >> a[i];
b[i] = b[i-1] + a[i];
}
int t;
cin >> t;
while (t--)
{
int l,r;
int sum = 0;
cin >> l >> r;
sum = b[r] - b[l-1];
printf("%d\n",sum);
}
return 0;
}
二维前缀和
二维前缀和
DP[i][j]表示(1,1)这个点与(i,j)这个点两个点分别为左上角和右下角所组成的矩阵内的数的和,好好想一下状态转移方程怎么来的呢?我们画一下图就知道了。
#include<iostream>
#include<cstring>
using namespace std;
int dp[2000][2000],map[2000][2000];
int main()
{
int m,n,k;//所给的矩阵是n*m的,有k组查询
cin >>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >>map[i][j];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)//预处理一波
for(int j=1;j<=m;j++)
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+map[i][j];
for(int i=1;i<=k;i++)//接受查询
{
int x1,x2,y1,y2;
cin >>x1>>y1>>x2>>y2;
cout <<(dp[x2][y2]+dp[x1-1][y1-1]-dp[x1-1][y2]-dp[x2][y1-1])<<endl;//O(1)查询
}
return 0;
}
)<<endl;//O(1)查询
}
return 0;
}
>
>
>借鉴于:[前缀和](https://www.cnblogs.com/-Ackerman/p/11162651.html) [前缀和](https://blog.csdn.net/qq_41661809/article/details/86727017)
>