poj 2029 Get Many Persimmon Trees

呃, 水题一枚,暴力就可以轻松过,但是还是想通过这种水题来让自己熟悉一下学过的算法,于是用了几种方法完成,呵呵,收获还是很多的~

1、暴力过了一下,1A,呃,这个代码就不贴了,自认为代码写的还是很烂的,跑了16ms。

2、二维树状数组。通过它终于弄明白二维树状数组是怎样求区间和的了。s[i][j] 表示从( 1 , 1 )->( i , j )的和,则要求( xi , yi )->( xj , yj )矩形的和话,则要表示为

s[xj][yj] + s[xi-1][yi-1] - s[xi-1][yj] - s[xj][yi-1] ,其实一画图就能明白的,

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
#define  N 102
using namespace std;

int ss[N][N] , w , h ;

int lowbit( int x )
{
    return x & ( -x );
}

void add ( int x , int y , int c )
{
    int i , j ;
    for ( i = x ; i <= w ; i+= lowbit( i ))
    for ( j = y ; j <= h ; j+= lowbit( j ))
    ss[i][j] += c ;
}

int sum ( int x , int y )
{
    int sx = 0 ;
    for ( int i = x ; i > 0 ; i -= lowbit( i ))
    for ( int j = y ; j > 0 ; j -= lowbit( j ))
    sx += ss[i][j] ;
    return sx ;
}

int main()
{
    int n , x , y , i , j ;

    while ( scanf( "%d" , &n ) , n )
    {
        scanf( "%d%d" , &w , &h );
        memset( ss , 0 , sizeof( ss ));
        for ( i = 0 ; i < n ; i++ )
        {
            scanf( "%d%d" , &x , &y );
            add( x , y , 1 );
        }
        scanf( "%d%d" , &x , &y );
        int maxx = -1 ;
        for ( i = x ; i <= w ; i++ )
        {
            for ( j = y ; j <= h ; j++ )
            {
                int sx = sum ( i , j ) + sum ( i - x , j - y ) - sum ( i - x , j ) - sum( i , j - y );
                if ( sx > maxx )
                maxx = sx ;
            }
        }
        cout<<maxx<<endl;
    }
    return 0 ;
}

3、动态规划,其实这题在训练计划上是属于较复杂的dp,但是我实在没想出来用dp怎么做,曾想过,要不把每个矩形的和存起来在用dp求最大值,但是一想,这样还不如直接暴力呢,然后上网上搜搜大牛们都是怎么用的dp,结果傻眼了,原来是用dp求各个矩形的和,然后在枚举求出最大值,好吧,这样做和上面用二维树状数组其实是一样的。

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#define  N  102
using namespace std ;

int dp[N][N] , w , h ;

int max ( int x , int y )
{
    return x > y ? x : y ;
}

int main()
{
    int n , i , j , x , y ;

    while ( scanf( "%d" , &n ) , n )
    {
        scanf( "%d%d" , &w , &h );
        memset( dp , 0 , sizeof( dp ));
        for ( i = 0 ; i < n ; i++ )
        {
            scanf( "%d%d" , &x , &y );
            dp[x][y] = 1 ;
        }

        /*for ( i = 1 ; i <= w ; i++ )
        {
            for ( j = 1 ; j <= h ; j++ )
            cout<<dp[i][j]<<" ";
            cout<<endl;
        }
        cout<<endl;*/

        for ( i = 1 ; i <= w ; i++ )
        for ( j = 1 ; j <= h ; j++ )
        dp[i][j] +=  dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] ;

        /*for ( i = 1 ; i <= w ; i++ )
        {
            for ( j = 1 ; j <= h ; j++ )
            cout<<dp[i][j]<<" ";
            cout<<endl;
        }*/

        scanf( "%d%d" , &x , &y );
        int maxx = -1 ;
        for ( i = x ; i <= w ; i++ )
        for ( j = y ; j <= h ; j++ )
        maxx = max ( maxx , dp[i][j] + dp[i-x][j-y] - dp[i-x][j] - dp[i][j-y] );

        cout<<maxx<<endl;
    }
    return 0 ;
}
posted @ 2012-08-11 16:38  Misty_1  阅读(157)  评论(0编辑  收藏  举报