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;
}