其他分享
首页 > 其他分享> > 前缀和与差分

前缀和与差分

作者:互联网

题目

1.P1115 最大子段和

思路:从一段序列中找出最大的连续子序列。可以把前面的相加,累加的和直到小于0时,将sum赋值为0重新开始累加。

#include <iostream>
using namespace std;
const int N = 1e6;
int n;
int num[N];
int ans;
int sum;
 
int main(int argc, char *argv[]) {
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		cin >> num[i] ;
		sum = sum > 0 ? sum : 0;
		sum = sum + num[i];
		if(i == 1)
		{
			ans = num[i];
		}
		else
		{
			ans = max(ans, sum);
		}
	}
	cout << ans;
	return 0;
}

2.P3397 地毯

思路:使用差分法进行运算即可完成,例如输入的时i,j,即可将下标i的数加上输入的数,将下标j+1的减去输入的数。还原的话将每一个元素加上前面一个元素即可复原。

#include <iostream>
using namespace std;
int n,  m;
int num[1005][1005];
int main() {
	static int x1, x2, y1, y2;
	cin >> n >> m;
	for(int i = 1; i <= m; i++)
	{
		cin >> x1 >> y1;
		cin >> x2 >> y2;
		for(int j = x1; j <= x2; j++)
		{
			num[j][y1]++;
			num[j][y2 + 1]--;                   //差分
		}
	}		
	for(int i = 1; i <= n; i++)
	{
		for(int j= 1; j <= n; j++)
		{
			num[i][j]+=num[i][j - 1];           //还原
			cout << num[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

3.P1719 最大加权矩形

思路:此题使用二维差分法
例如:一个二维数组,进行差分时使用
\(num[i][j] = cha[i][j] - cha[i - 1][j] - cha[i][j - 1] + cha[i - 1][j - 1]\)
使用了二维差分后求(x1,y1)到(x2,y2)矩阵中数据的和即可使用求出来的差分数组,即
\(cha[x2][y2] - cha[x1 - 1][y2] - cha[x2][y1- 1] + cha[x1 - 1][y1 - 1]\)。

#include <iostream>
using namespace std;
int n;
int t;
int num[130][130];
int cha[130][130];
int ans = -0xffffff;

int main(int argc, char *argv[]) {
	cin >> n;
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
		{
			cin >> num[i][j];
			cha[i][j] = cha[i - 1][j] + cha[i][j - 1] - cha[i - 1][j - 1] + num[i][j];
		}		
	for(int x1 = 1; x1 <= n; x1++)
		for(int y1 = 1; y1 <= n; y1++)
			for(int x2 = 1; x2 <= n; x2++)
				for(int y2 = 1; y2 <= n; y2++)
					if(x2 < x1 || y2 < y1)
						continue;
					else
					 	ans = max(ans, cha[x2][y2]-cha[x1-1][y2]-cha[x2][y1-1]+cha[x1-1][y1-1]);
	cout << ans;
	
	return 0;
}

标签:cha,前缀,int,sum,差分,num,ans,x1
来源: https://www.cnblogs.com/citurs/p/16069819.html