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; }