HDU2524-矩形A + B
Problem Description
给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形
Input
第一行输入一个t, 表示有t组数据,然后每行输入n,m,分别表示网格的高和宽 ( n < 100 , m < 100).
Output
每行输出网格中有多少个矩形.
Sample Input
2
1 2
2 4
Sample Output
3
30
题解
思路一
我们假设网格是1行m列的,那么总的矩形数目 = m(1*1的矩形) + m-1(1*2的矩形) + m-2(1*3的矩形) +…+1(1*m的矩形) = ,同理n行1列总的矩形数目是 . 对于 的网格,我们可以先确定好选取的行数(即确定矩形的高),共有 种选法,选好以后就可以压缩成1行m列的网格来考虑了,因此总共 个矩形。
思路二
动态规划,假设dp[i][j]表示以第 i 行第 j 列的格子为右下角顶点的矩形数目,那么dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1] , 这里的1表示i ,j 位置的格子自身构成1*1的矩形,之所以减去dp[i-1][j-1], 因为dp[i-1][j] 和 dp[i][j-1] 都包含了dp[i-1][j-1]。最后把所有dp[i][j]加起来就是我们所求的答案。
计算时注意i = 1 和 j = 1的边界条件。dp[][0]=dp[0][]=1;dp[0][0]=2 (因为dp[1][1]=1+dp[1][0]+dp[0][1]-dp[0][0]=1,所以dp[0][0]=2)
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
LL ans=(n*(1+n)/2)*(m*(1+m)/2);
printf("%lld\n",ans);
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn=105;
LL dp[maxn][maxn];
void init()
{
for(int i=0;i<maxn;++i)
dp[i][0]=dp[0][i]=1;
dp[0][0]=2;
for(int i=1;i<maxn;++i)
for(int j=1;j<maxn;++j)
dp[i][j]=1+dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
}
void solve2(int n,int m)
{
LL ans=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
ans+=dp[i][j];
printf("%lld\n",ans);
}
int main()
{
init();
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
solve2(n,m); //方法二
}
return 0;
}