一、整体思路
1、计算一共存在多少个正方形和长方形
对于n*m的长方形一共有n * (n + 1) / 2 * m * (m + 1) / 2 个内置正方形和长方形
2、算正方形个数(长方形个数只需要总数减去正方形个数就行)
我们假设i*j的长方形中,右下角(坐标i, j)为正方形固定的右下角,那所包含的正方形只能有min(i, j)个
其他所有的可能正方形均为右下角坐标非(i, j)的正方形,那就是长方形(i-1)*j和长方形i*(j-1)中的正方形,但是其中我们把(i-1)*(j-1)中包含的正方形多算了一次,因此减去就可以了
3、得出最后的递推代码片段
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + min(i, j)
4、优化:因为本题如果直接开数组需要50005000,爆内存了,因此就用25000的进行记录和优化迭代。
二、整体代码
#include<iostream>
#include<math.h>
#include <algorithm>
using namespace std;
int main() {
long long int n, m, i, j;
while(cin>>n>>m) {
long long int a[3][5010] = {0};
for(i = 1; i <= n; i++) {
for(j = 1; j <= m; j++) {
if(i == 1)
a[2][j] = a[2][j - 1] + 1;
else if(j == 1)
a[2][j] = a[1][j] + 1;
else
a[2][j] = a[1][j] + a[2][j - 1] - a[1][j - 1] + min(i, j);
}
for(j = 1; j <= m; j++)
a[1][j] = a[2][j];
}
cout<<a[2][m]<<" "<<(long long int)(n + 1) * (long long int)n * (long long int)(m + 1) * (long long int)m / (long long int)4 - a[2][m]<<endl;
}
}