zoukankan      html  css  js  c++  java
  • 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 ;
    }
  • 相关阅读:
    Python入门学习笔记07(time)
    Python入门学习笔记01(常用数据类型)
    Python入门学习笔记04(生成器与迭代器)
    Python入门学习笔记05(内置函数)
    Python入门学习笔记 序
    Python入门学习笔记03(装饰器)
    Python入门学习笔记02(文件的打开、读写)
    Python入门学习笔记06(shelve模块)
    main参数
    [转]如何自动将c++程序接口封装供Python调用
  • 原文地址:https://www.cnblogs.com/misty1/p/2633774.html
Copyright © 2011-2022 走看看