关于二维树状数组请参看:http://128kj.iteye.com/blog/1746732
poj2029题意:
在一块h*w的地上,有n棵柿子树,划t*s的一块矩形地,使得其划到的柿子树最多,输出最多的数量.

样例:
16 //有多少棵树
10 8 //地的规模h*w
2 2 //(2,2)处有一棵树
2 5
2 7
3 3
3 8
4 2
4 5
4 8
6 4
6 7
7 5
7 8
8 1
8 4
9 6
10 3
4 3 //划t*s的一块地,这里是t和s
8
6 4
1 2
2 1
2 4
3 4
4 2
5 3
6 1
6 2
3 2
0

很明显的二维树状数组,穷举t*s的所有位置,并记录其划到的树的个数和最大值.

下面是AC代码:

Java代码
  1. import java.util.Scanner;
  2. public class Main{
  3. static final int N=102;
  4. int C[][];//二维树状数组
  5. int w;
  6. int h ;
  7.  
  8. private int lowbit(int x ){
  9. return x & ( -x );
  10. }
  11.  
  12. private void Modify( int x , int y , int c ){
  13. for (int i = x ; i <= w ; i+= lowbit( i ))
  14. for (int j = y ; j <= h ; j+= lowbit( j ))
  15. C[i][j] += c ;
  16. }
  17.  
  18. private int Sum (int x , int y ){
  19. int result = 0 ;
  20. for ( int i = x ; i > 0 ; i -= lowbit( i ))
  21. for ( int j = y ; j > 0 ; j -= lowbit( j ))
  22. result += C[i][j] ;
  23. return result ;
  24. }
  25.  
  26. public static void main(String[] args){
  27. Main ma=new Main();
  28. ma.go();
  29. }
  30.  
  31. private void go(){
  32. Scanner in=new Scanner(System.in);
  33. int n , x , y;
  34. while(true) {
  35. n=in.nextInt();
  36. if(n==0) break;
  37. w=in.nextInt();
  38. h=in.nextInt();
  39. C=new int[w+1][h+1];
  40. for (int i = 0 ; i < n ; i++ ){
  41. x=in.nextInt();
  42. y=in.nextInt();
  43. Modify(x,y,1 );//将原矩阵(x,y)处的值设置为1,并更新二维树状数组
  44. }
  45. x=in.nextInt();
  46. y=in.nextInt();
  47. int maxx = -1 ;
  48. int sx=0;
  49. for (int i = x ; i <= w ; i++ )
  50. {
  51. for (int j = y ; j <= h ; j++ )
  52. {
  53. sx = Sum (i,j) + Sum (i-x,j-y)-Sum(i-x,j)-Sum(i,j- y );
  54. if ( sx > maxx )
  55. maxx = sx ;
  56. }
  57. }
  58. System.out.println(maxx);
  59. }
  60. }
  61. }