DP練習 月餅盒(提高版)

2021-08-20 14:31:56 字數 1721 閱讀 8849

【題目背景】:中秋節了,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 ...