hoj1644 City Game dp

周赛的题目,思想

011111

111111

000111

111111

111111

转换为

011111

122222

000333

111444

222555

然后按该位置的高度向两边扩展,当遇到小于该高度时,停止扩展,然后用右边的下标减左边的下标加一,

再乘以当前的高度即为所求,dp的实现是在计算第二个矩阵时用到的,只是简单的

h[i,j] = h[i-1,j]+1      (map[i][j]=='F')

 

#include <cstring>

#include <iostream>

#include <string>

using namespace std;

#define X 1005

string s;

int map[X][X],dp[X][X],l[X],r[X],m,n;

int main()

{

   freopen("sum.in","r",stdin);

   freopen("sum.out","w",stdout);

   int t;

   cin>>t;

   while(t--)

   {

      cin>>m>>n;

      memset(map,0,sizeof(map));

      for(int i=1;i<=m;i++)

      {

         for(int j=1;j<=n;j++)

         {

            cin>>s;

            if(s=="F")

                map[i][j] = 1;

         }

      }

      for(int i=2;i<=m;i++)

         for(int j=1;j<=n;j++)

            if(map[i][j])

                map[i][j] = map[i-1][j]+1;

      int ans = 0;

      for(int i=1;i<=n;i++)

         if(map[1][i])

            ans = 1;

      for(int i=2;i<=m;i++)

      {

         for(int j=1;j<=n;j++) //向左扩展

         {

            l[j] = j;

            while(l[j]>1&&map[i][l[j]-1]>=map[i][j])

                l[j]--;

         }

         for(int j=1;j<=n;j++) //向右扩展

         {

            r[j] = j;

            while(r[j]<n&&map[i][r[j]+1]>=map[i][j])

                r[j]++;

         }

         for(int j=1;j<=n;j++) //更新当前的最大矩阵

            if((r[j]-l[j]+1)*map[i][j]>ans)

                ans = (r[j]-l[j]+1)*map[i][j];

      }

      cout<<ans*3<<endl;       //3倍数输出

   }

   return 0;

}

 

你可能感兴趣的:(game)