现在的位置: 首页 > 综合 > 正文

ZOJ 3616 Choir III

2018年01月11日 ⁄ 综合 ⁄ 共 1588字 ⁄ 字号 评论关闭

题意:给一个n*m的矩阵,这个矩阵中的第i行j列有一个欢乐值和这个位置的人的性别,如果欢乐值为负数的话就不能选这个人。

求:选择一个子矩阵,这个子矩阵中不能包含欢乐值为负数,并且这个矩阵中男孩的个数大于等于b,这个矩阵中女孩的个数大于等于g  (n,m,b,g都将给出)

(n<=100,m<=2000)


我的做法:

n*n*m的复杂度

我一开始是这么想的。

输入这个矩阵之后,预处理行的欢乐值,男孩的个数,女孩的个数,再预处理左上角到该点一共有多少欢乐值。男孩的个数。女孩的个数。然后求出所有欢乐值为负数的点。然后按列排序。最后枚举行,对列的开始点和终点进行判断。这样做的结果是TLE了。。

后来观察大牛的代码发现我还是太天真了。大牛的代码是预处理列。因为要枚举行。所以只需要预处理列就可以了。。

因为我的预处理是行预处理的,但是我又枚举行。这样的话计算起来不是很方便。。

还是太天真了,不多说。上代码。


//author: CHC
//First Edit Time:	2014-07-20 22:02
//Last Edit Time:	2014-07-20 22:34
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
#define MAXN 110
#define MAXM 2010
typedef long long LL;
int n,m,b,g;
int sgi[MAXN][MAXM];
int sbi[MAXN][MAXM];
LL svi[MAXN][MAXM];
int st[MAXN][MAXM];
int sv[MAXN][MAXM];
int last[MAXN][MAXM];
int main()
{
    memset(sgi,0,sizeof(sgi));
    memset(sbi,0,sizeof(sbi));
    memset(svi,0,sizeof(svi));
    memset(last,0,sizeof(last));
    while(~scanf("%d%d%d%d",&n,&m,&b,&g)){
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d%d",&sv[i][j],&st[i][j]);
        for(int j=1;j<=m;j++)
        for(int i=1;i<=n;i++){
            sbi[i][j]=sbi[i-1][j]+(st[i][j]==1);
            sgi[i][j]=sgi[i-1][j]+(st[i][j]==2);
            svi[i][j]=svi[i-1][j]+sv[i][j];
            last[i][j]=last[i-1][j];
            if(sv[i][j]<0)last[i][j]=i;
        }
        LL ans=-1;
        for(int x=1;x<=n;x++){
        for(int x1=x;x1<=n;x1++){
            LL nv,nb,ng,lv,lb,lg;
            nv=nb=ng=lv=lb=lg=0;
            for(int i=1;i<=m;i++){
                nv+=svi[x1][i]-svi[x-1][i];
                nb+=sbi[x1][i]-sbi[x-1][i];
                ng+=sgi[x1][i]-sgi[x-1][i];
                if(last[x1][i]>=x){
                    lv=nv;
                    lb=nb;
                    lg=ng;
                    continue;
                }
                if(nb-lb>=b&&ng-lg>=g){
                    ans=max(ans,nv-lv);
                }
            }
        }
        }
        if(ans==-1)puts("No solution!");
        else printf("%lld\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.