ZOJ 3616Choir III

来源:互联网 发布:司芬克斯 知乎 编辑:程序博客网 时间:2024/05/11 05:40

题意:给一个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 2010typedef 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;}


0 0
原创粉丝点击