TopCoder-SRM636-DIV1-250pt

http://community.topcoder.com/stat?c=problem_statement&pm=13497&rd=16079

一道简单题。首先能估算出,枚举所有分割的可能是C(n,2)*C(m,2)=O(m^2*n^2)。但是如果已知分割后再遍历所有字符则会超时。

所以这道题的重点就是预计算。预计算一个at[p][q]表,表中每个元素为[0,p)*[0,q)的累加和。然后根据这个预计算表和分割通过集合求并的方式计算出分割里每一块的大小。得到答案。

        int findBest(vector <string> chocolate) 
            { 
                vector <string> &cho=chocolate;
                n=cho.size();
                m=cho[0].size();
                //pre-table
                vector<vector<int>> at(n+1,vector<int>(m+1,0));
                for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
                    at[i][j]=(cho[i-1][j-1]-'0')+at[i-1][j]+at[i][j-1]-at[i-1][j-1];
                }
                int res=0;
                for(int x0=1;x0<n-1;x0++) for(int x1=x0+1;x1<n;x1++) {
                    for(int y0=1;y0<m-1;y0++) for(int y1=y0+1;y1<m;y1++){
                        vector<vector<int>> a(3,vector<int>(3,0));
                        int cx[4];
                        int cy[4];
                        cx[0]=0;cx[1]=x0;cx[2]=x1;cx[3]=n;
                        cy[0]=0;cy[1]=y0;cy[2]=y1;cy[3]=m;
                        int minv=numeric_limits<int>::max();
                        for(int i=1;i<=3;i++) for(int j=1;j<=3;j++){
                            minv=min(minv,at[cx[i]][cy[j]]-at[cx[i-1]][cy[j]]-at[cx[i]][cy[j-1]]+at[cx[i-1]][cy[j-1]]);
                        }
                        res=max(res,minv);
                    }
                }
                return res;
            } 

 

posted @ 2014-10-22 22:00  zombies  阅读(268)  评论(0编辑  收藏  举报