PKU ACM1050——穷举、穷举简化、分治、动态规划

一、PKU ACM1050——穷举、穷举简化、分治、动态规划

穷举法:

     找出所有矩形的值,一个一个比较求出最大值。时间复杂度O(N^4),空间复杂度O(1)

 

int func(int **pMatrix,int num)

{

     int max = INT_MIN;

     int sum = 0;

     int maxI = 0;//最大值出现的矩形左上角的列下标

     int maxJ = 0;最大值出现的矩形左上角的行下标

     int maxII = 0;//最大值出现的矩形右下角的列下标

     int maxJJ = 0;//最大值出现的矩形右下角的行下标

     int i = 0;//当前矩形左上角的列下标

     int j = 0;//当前矩形左上角的行下标

     int ii = 0;//当前矩形右下角的列下标

     int jj = 0;//当前矩形右下角的行下标

     int n = 0;//当前元素列下标

     int m = 0;//当前元素行下标

    

     for(i = 0;i < num;i++)

         for(j = 0;j < num;j++)

         {

              cout << "i=" << i << endl;

              cout << "j=" << j << endl;

              cout << endl;

              for(ii = i;ii < num;ii++)

                   for(jj = j ;jj < num;jj++)

                   {

                       cout << "ii=" << ii << endl;

                       cout << "jj=" << jj << endl;

                       cout << endl;

                       for(n = i;n <= ii;n++)

                       {

                            for(m = j;m <= jj;m++)

                            {

                                 sum += pMatrix[n][m];

                            }

                       }

                       cout << "sum=" << sum;

                        cout << endl;

                       if(sum > max)

                       {

                            max = sum;

                            maxII = ii;

                            maxJJ = jj;

                            maxI = i;

                            maxJ = j;

 

                            cout << "########" << endl;

                            cout << "sum=" << sum << endl;

                            cout << "########" << endl;

                       }

                       sum = 0;

                       //system("pause");

                   }

         }

 

     return max;

}

穷举法简化:

       举例子,在

         0,-2,-7,0,

         9,2,-6,2,

 

         -4,1,-4,1,

         -1,8,0,-2

中,求矩形

         0,-2,-7,0,

         9,2,-6,2

可在

         0,-2,-7,

         9,2,-6

基础上加上

0

2

即可计算出来。若函数a(li,lj,ri,rj)表示所求矩形的值,四形参的值分别表示,矩形左上角值的行下标,矩形左上角值的列下标,矩形右下角值的行下标,矩形右下角值的列下标。则a(li,lj,ri,rj+1)= a(li,lj,ri,rj)+ a(0,rj,0,rj)+ a(1,rj,1,rj)+……+ a(ri,rj,ri,rj)

但是时间复杂度仍是O(N^4),空间复杂度O(1)

 

分治法:

将数组从中间切开,分为两半。则该数组的最大矩形和有三种情况:

1)  其与数组左半部分的最大矩形和相同;

2)  其与数组右半部分的最大矩形和相同;

3)  其值= a(li,lj,ri,rj)lj<=n/2,rj>=n/2+1

 

对前两种情况再次使用“切开”。

而对第三种情况,如下计算——在左右两半数组各计算出所有符合下列情况的矩形和:该矩形一定包含边界上的元素,该矩形行数范围是1~n,列数范围是1~n/2。然后左右数组将对应(左右放到一起可以组成一个矩形的)的矩形和相加,求出当中的最大值,该值即为第三种情况下的最大矩形和。

 

设计出的递归函数算法如下:

1)  求出数组左半部分最大矩形和;

2)  求出数组右半部分最大矩形和;

3)  求出跨越数组左右两部分的最大矩形和;

4)  将以上三值比较,返回最大值。

 

动态规划法:

网上搜的算法很多是从一维衍生到二维的,以下转载《编程之美》对一维的分析。

方法---动态规划法

0 = i = j,元素A[0]本身构成和最大的一段;

0 = i < j,和最大的一段以A[0]开始;

0 < i,和最大的一段与A[0]没有关系;

假设(A[1], ,A[n-1])中和最大的一段之和为All[1],并且已经知道(A[1], ,A[n-1])中包含A[1]的和最大的一段为Start[1],可以看出(A[0], ,A[n-1])中问题的解All[0]是三种情况最大值max{A[0], A[0] + Start[1] , All[1]}。符合无后效性,用动态规划法求解。

int max(int x, int y)

{

return (x > y) ? x : y;

}

int MaxSum(int *A , int n )

{

Start[n-1] = A[n-1];

All[n-1] = A[n-1];

for(int i = n - 2; i >= 0; i--)

{

Start[i] = max(A[i], A[i]+Start[i+1]);

All[i] = max(Start[i], All[i+1]);

}

return All[0];

}

基本思想是懂的,但是怎么转化到分析这个二维数组呢?倒是有问题,比较笨,暂时MARK下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值