题目1 : 矩形计数
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
如图所示,在由N行M列个单位正方形组成的矩形中,有K个单位正方形是黑色的,其余单位正方形是白色的。
你能统计出一共有多少个不同的子矩形是完全由白色单位正方形组成的吗?
输入
第一行三个整数:N, M和K。
之后K行每行包括两个整数R和C,代表一个黑色单位正方形的位置。
1 <= N,M <= 1000
1 <= K <= 10
1 <= R <= N
1 <= C <= M
输出
输出一个整数表示满足条件的子矩形个数。
样例输入
3 3 1 2 3
样例输出
24
建立一种二维表,定义f(i,j)表示以点(i,j) 右上方矩形的个数。最终f(n,m)即为答案。 动态规划是f(i,j)=f(i-1,j)+f(i,j-1)-f(i-1,j-1)+now now表示以点(i,j)为右下角的矩形的个数
package Daily;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;
public class Main_234 {
int n,m;
long dp[][];
LinkedList<Node>black = new LinkedList<>();
long solve(){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j++){
int now = 0;
int lastX =0;
int lastY = j;
for(int k = black.size() - 1; k >= -1 ; k --){
Node p;
if(k == -1) p = new Node(i, 0);
else p = black.get(k);
if(p.y > j ) continue;
if(p.x > i || p.x < lastX) continue;
now += (i - lastX) * (lastY - p.y);
lastX = p.x;
lastY = p.y;
}
dp[i][j] = dp[i -1 ][j] + dp[i][j -1 ] - dp[i - 1][j - 1] + now;
}
}
return dp[n][m];
}
Main_234(){
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
m = cin.nextInt();
dp = new long[n +1 ][ m +1];
int k = cin.nextInt();
while(k -- > 0){
int r = cin.nextInt(), c = cin.nextInt();
black.add(new Node(r,c));
}
black.sort(new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
if(o1.y == o2.y) return o1.x - o2.x;
return o1.y - o2.y;
}
});
// black.sort(Comparator.comparing(x->x.y));
for(int i = 0 ; i <= n; i ++) dp[i][0] = 0;
for(int i =0; i < m ; i ++) dp[0][i] = 0;
long ans = solve();
System.out.println(ans);
}
public static void main(String []args){
new Main_234();
}
static class Node{
private int x;
private int y;
Node(int x, int y ){
this.x = x;
this.y = y;
}
}
}