【題目背景】:中秋節了,did老師決定去送禮。
【問題描述】:乙個被分為 n*m 個格仔的月餅盒,第 i 行第 j 列位置的格仔裡面有 a [ i , j ]個月餅。本來did老師打算送這盒月餅給某人的,但是就在要送出月餅盒的前一天晚上,乙隻極其可惡的老鼠夜襲月餅盒,有部分格仔被洗劫並且穿了洞。did老師必須盡快從這個月餅盒裡面切割出乙個矩形月餅盒,新的月餅盒不能有洞,並且did老師希望保留在新月餅盒內的月餅的總數盡量多。
【題目任務】:請幫did老師設計乙個程式 計算一下新月餅盒最多能夠保留多少月餅。
【檔案輸入】:第一行有兩個整數 n、m。第 i + 1 行的第 j 個數表示 a [ i , j ],如果這個數為 0 ,則表示這個位置的格仔被洗劫過。其中: 0 ≤ a [ i , j ]≤ 1000
【檔案輸出】:輸出最大月餅數
【樣例輸入】
3 41 2 3 4
5 0 6 3
10 3 4 0
【樣例輸出】
17ps:對於40%的資料,n ,m≤80
對於60%的資料,n ,m≤400
對於100%的資料,n,m≤1000
題解:對於(i,j)這個格仔,我們如果將以它為某矩形底邊的乙個格仔,它向上可以達到高為h[i][j],我們把這個看成一條高為h[i][j]的一條線段,讓這條線段向左右盡可能長地擺動,假設他能夠擺動的長度分別為l[i][j]和r[i][j],這樣能夠得到乙個以(i,j)為底邊一點的最大矩陣(即可以確定矩形的左上腳座標和右下腳座標),這樣我們用遞推就可以一次性算出這個矩陣的權值。如下圖。
h[i,j]、l[i,j]、r[i,j]都可以遞推得到:
當格仔中的數為0的時候h[i][j]=0,否則h[i][j]=h[i-1][j]+1;
當格仔中的數為0的時候l[i][j]=0,否則l[i][j]=l[i][j-1]+1;
當格仔中的數為0的時候r[i][j]=0,否則r[i][j]=r[i][j+1]+1;
**貼上:
#include#includeusing namespace std;
int x2,x1,y1,y2,c,n,m,a[1005][1005],h[1005][1005],r[1005][1005],l[1005][1005],ans,maxx;
int main()
for(int j=1;j<=m;j++)
if(h[i][j]==0) l[i][j]=0;
else l[i][j]=l[i][j-1]+1;
for(int j=m;j>=1;j--)
if(h[i][j]==0) r[i][j]=0;
else r[i][j]=r[i][j+1]+1;
} for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(h[i][j]>0)
x2=i;y2=j+r[i][j]-1;
x1=i-h[i][j]+1;y1=j-l[i][j]+1;
maxx=a[x2][y2]-a[x2][y1-1]-a[x1-1][y2]+a[x1-1][y1-1];
ans=max(ans,maxx);
} printf("%d",ans);
return 0;
}
僅為個人見解,若有不好之處,歡迎反映交流! DP練習 月餅盒(提高版)(vijos1255)
題目背景 中秋節了,ccc老師決定去送禮。問題描述 乙個被分為 n m 個格仔的月餅盒,第 i 行第 j 列位置的格仔裡面有 a i j 個月餅。本來ccc老師打算送這盒月餅給某人的,但是就在要送出月餅盒的前一天晚上,乙隻極其可惡的老鼠夜襲月餅盒,有部分格仔被洗劫並且穿了洞。ccc老師必須盡快從這個...
區間DP練習
部落格 lightoj 1422 int dp 105 105 a 105 dp i j i 到 j 最小穿多少衣服 int main printf d n dp 1 n return 0 poj2955括號匹配 int dp 105 105 a 105 dp i j i 到 j 匹配了多少括號。i...
數字DP練習
數字dp模板 hdu2089 不要62 題意 求區間中不含62且不含4的數的個數 include include includeusing namespace std int dp 20 10 int a 20 sta 記錄上一位數是否是6 int dfs int pos,int sta,bool ...