前缀和与差分
作者:互联网
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