P1055 奶牛浴场 - Vijos

2014-11-23 23:40:18 · 作者: · 浏览: 3
极大化思想解决最大子矩阵问题。具体是从http://wenku.baidu.com/view/bc8311f69e314332396893f7. html这里学到的,是这个里面的例题。。这里面讲了两种方法,暂时只用了第一种方法,第二种方法以后再补上吧。具体思想ppt中都讲得很清楚了,这里只粘一下代码吧。。
第一种方法:
#include  
#include  
#include  
#include  
#include  
#define CLR(a, b) memset(a, b, sizeof(a))  
  
using namespace std;  
typedef long long LL;  
const int N = 5050;  
  
struct Point  
{  
    int x, y;  
    bool operator < (const Point& rhs) const  
    {  
        return x < rhs.x || (x == rhs.x && y < rhs.y);  
    }  
}p[N];  
  
bool vis[2][2], hav[N * 6];  
int n, x, y, l, w;  
  
int solve()  
{  
    int ret = 0, u, d = 0, s;  
    for(int i = 0; i <= w; i ++)  
    {  
        if(vis[hav[i]])  
        {  
            ret = max(ret, l * (i - d));  
            d = i;  
        }  
    }  
    for(int i = 0; i < n; i ++)  
    {  
        u = w, d = 0;s = i;  
        while(p[s].x == p[i].x && s < n) s ++;  
        for(int j = s; j < n; j ++)  
        {  
            ret = max(ret, (u - d) * (p[j].x - p[i].x));  
            if(p[j].y > p[i].y && p[j].y < u) u = p[j].y;  
            else if(p[j].y <= p[i].y && p[j].y >
d)d = p[j].y; } ret = max(ret, (u - d) * (l - p[i].x)); } for(int i = n - 1; i >= 0; i --) { u = w, d = 0;s = i; while(p[s].x == p[i].x && s >= 0) s --; for(int j = s; j >= 0; j --) { ret = max(ret, (u - d) * (p[i].x - p[j].x)); if(p[j].y > p[i].y && p[j].y < u) u = p[j].y; else if(p[j].y <= p[i].y && p[j].y > d)d = p[j].y; } ret = max(ret, (u - d) * p[i].x); } return ret; } int main() { //freopen("input.txt", "r", stdin); while(~scanf("%d%d", &l, &w)) { scanf("%d", &n);CLR(vis, 0); CLR(hav, 0); for(int i = 0; i < n; i ++) { scanf("%d%d", &x, &y); p[i].x = x, p[i].y = y; if(x == 0 && y == 0) vis[0][0] = 1; if(x == l && y == 0) vis[1][0] = 1; if(x == 0 && y == w) vis[0][1] = 1; if(x == l && y == w) vis[1][1] = 1; } for(int i = 0; i < 2; i ++) for(int j = 0; j < 2; j ++) if(!vis[i][j]) { p[n].x = i * l; p[n ++].y = j * w; } sort(p, p + n); printf("%d\n", solve()); } }