洛谷P4417 [COCI2006-2007#2] STOL
阿新 • • 發佈:2018-12-08
題目描述
米爾科買了一套別墅,他想要邀請儘量多的人和他一起慶祝。他需要一張大的木質矩形桌子來讓他和他的嘉賓坐下。每張桌子可容納的人數等於它的周長(四邊長度的總和)。米爾科想要買一張即可在他的公寓裡放下,也可以坐下儘量多的人和他一起享用晚餐的桌子。桌子必須放置成四條邊都與公寓的牆平行的樣子。題目給出公寓內部的佈局,請問米爾科最多可以邀請多少人吃晚餐。
輸入輸出格式
輸入格式:
第一行包含兩個整數R和S(1<=R,S<=400),代表公寓的尺寸(R為寬,S為長),以下的R行中每一行都包含了S個準確的字元(沒有空格),代表這個正方形區域是沒有東西的('.') ,還是有東西的('X'),米爾科只等把桌子發在沒有東西的正方形區域裡。
輸出格式
輸出米爾科在放下他的桌子後能夠邀請來吃晚餐的人數
輸入輸出樣例
輸入樣例#1:
2 2
..
..
輸出樣例#1:
7
輸入樣例#2:
4 4
X.XX
X..X
..X.
..XX
輸出樣例#2:
9
輸入樣例#3:
3 3
X.X
.X.
X.X
輸出樣例#3:
3
經過觀察得出,這題需要打O(n^2)-O(n^3)的題解,先考慮O(n^3)的解
首先列舉行和列
因為需要找出1-i行可以形成的矩形,所以我們另k從i搜尋到1
要成為矩形,每一行的連續空餘位置都必須一樣,所以sum[ i ] [ j ]表示第i行的第j列又多少個連續的空餘位置
如果要每一行的連續空餘位置一樣並且矩陣周長最大化,那麼矩陣的長度就是由目前找過最小的sum來決定
當搜尋到X時,就退出,每次找到矩陣都記錄一次最大值,故時間保證在O(n^3)以內
我講的不是很清晰,希望我清晰的程式碼能夠幫助您
程式碼:
#include<cstdio> #include<cstring> #include<iostream> #include<string> using namespace std; const int N=4e2+10; int n,m; int sum[N][N]; int maxx=0; string s; int read(){//弱智讀入 int t;cin>>t; return t; } int print(int x){//弱智輸出 cout<<x<<endl; } int solve(int x,int y){//長和寬分別為x和y的矩陣的周長 return (x+y)<<1; } int main(){ n=read();m=read(); for(int i=1;i<=n;i++){ cin>>s; for(int j=0;j<m;j++) if(s[j]=='.')sum[i][j+1]=sum[i][j]+1;//記錄字首和 } int minn; for(int i=1;i<=n;i++)//列舉 for(int j=1;j<=m;j++){ minn=999999999;//記錄行的最小字首 for(int k=i;k>=1;k--){ minn=min(minn,sum[k][j]); if(!minn)break;//當然不能為0 maxx=max(maxx,solve(i-k+1,minn));//記錄最大值 } } print(maxx-1);return 0; }