CF375B dp

来源:互联网 发布:js 获取元素当前位置 编辑:程序博客网 时间:2024/06/06 14:18

题目说可以重新排列行,先求出每个数右边有多少个连续的1.


然后,我们枚举列,按照每一列中的每个数的右边有多少个连续的1排序。

我直接用sort超时了,看了别人的做法,是这样的。

因为每个数右边连续的1的个数肯定不会超过列数m,所以就hash记录下每个数出现的次数,然后去枚举m到1,去更新答案。

具体可以看代码。

#include <iostream>#include <cmath>#include <algorithm>#include <string>#include <deque>#include <cstring>#include <cstdio>#include <vector>#include <set>#include <map>#include <queue>#include <cstdlib>#include <iomanip>using namespace std;#define rep(i, a, b) for( i = (a); i <= (b); i++)#define reps(i, a, b) for( i = (a); i < (b); i++)#define pb push_back#define ps push#define mp make_pair#define CLR(x,t) memset(x,t,sizeof x)#define LEN(X) strlen(X)#define F first#define S second#define Debug(x) cout<<#x<<"="<<x<<endl;const double euler_r = 0.57721566490153286060651209;const double pi = 3.141592653589793238462643383279;const double E = 2.7182818284590452353602874713526;const int inf=~0U>>1;const int MOD = int(1e9) + 7;const double EPS=1e-6;typedef long long LL;#define M 5050int a[M][M], c[M][M], h[M], HASH[M];char s[M];bool cmp(const int& a, const int& b){    return a > b;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n, m, i, j, k, ans;    scanf("%d%d",&n,&m);    for(i = 1; i <= n; i++)    {        scanf("%s",s);        for(j = 1; j <= m; j++) a[i][j] = s[j-1] - '0';    }    rep(i, 1, n)    {        for(j = m; j >= 1; j--)        {            if(a[i][j]) c[i][j] = c[i][j+1] + 1;        }    }    ans = 0;    rep(j, 1, m)    {        //每个数肯定不会超过列数m        rep(i, 1, n)        {            if(c[i][j]) HASH[c[i][j]]++;        }        int cnt = 0;        for(k = m; k >= 1; k--)        {            cnt += HASH[k];            HASH[k] = 0;            ans = max(ans, k * cnt);        }    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击