hdu 1505 City Game(dp)

小记:思路不对,努力白费


思路:同1506一样,一行一样的算,当算到某一行时,我们可以将这一行以及以上的所有行,看成是1506的样子,即这一行每个点都能形成的最大矩形是多大,

计算方法和1506一样,每个点记录左起和右起连续最长的长度.而高度,则是对每一行的每一点记录从第一行开始时到当前这一行,在当前这一点往上不碰到R的最大值

高度就相当于1506的高度。 因此问题转化了过来,只不过变成了个二维的问题。

老实说,我也没想到可以变成这个样子. 这个转化的能力还有待提高.


code:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 1010;
const int N = 3000010;
const int INF = 0x7fffffff;

bool mp[MAX_][MAX_];
int l[MAX_], r[MAX_];
int h[MAX_];

int main(){
	int n, T, m, ans;
	char c, str[10];
    scanf("%d", &T);
	while(T--){
	    scanf("%d%d", &n, &m);
	    REP(i, 0, n){
	        REP(j, 0, m){
	        //getchar();
            //scanf("%c", &c);这样用c接收必错! WA了一次
            scanf("%s", str);
            switch(str[0]){
                case 'R': mp[i][j] = 1;//printf("%c ", 'R');
                break;
                case 'F': mp[i][j] = 0;//printf("%c ", 'F');
                break;
            }
	    }
	    //printf("\n");
	    }

	    mst(h, 0);
        //printf("ok\n");
	    ans = -1;

	    REP(i, 0, n){

	        REP(j, 0, m){
	            if(mp[i][j]) h[j] = 0;
	            else h[j]++;
            }

            REP(x, 0, m){
                l[x] = r[x] = x;
            }

            REP(x, 0, m){
                while(l[x] > 0 && h[l[x] - 1] >= h[x]){
                    l[x] = l[l[x] - 1];
                }
            }

            for(int x = m - 1; x > -1; --x){
                while(r[x]+1 < m && h[r[x] + 1] >= h[x]){
                    r[x] = r[r[x] + 1];//printf("cao!\n");
                }
            }

            REP(j, 0, m){
                int tmp = h[j] * (r[j] - l[j] + 1);
                ans = max(ans, tmp);
            }
	    }
	    printf("%d\n", ans*3);

	}
	return 0;
}


你可能感兴趣的:(hdu 1505 City Game(dp))