在 n×m 的矩陣中,每個格仔有乙個權值,要求尋找乙個包含 k 個格仔的凸連通塊(連通塊中間沒有空缺,並且輪廓是凸的),使這個連通塊中的格仔的權值和最大。
注意:凸連通塊是指:連續的若干行,每行的左端點列號先遞減、後遞增,右端點列號先遞增、後遞減。
求出這個最大的權值和,並給出連通塊的具體方案,輸出任意一種方案即可。
輸入格式
第一行包含三個整數n,m和k。
接下來n行每行m個整數,表示n*m的矩陣上每個格仔的權值(均不超過1000)。
輸出格式
第一行輸出「oil : x」,其中x為最大權值和。
接下來k行每行兩個整數xi和yi,用來描述所有格仔的具體位置,每個格仔位於第xi行,第yi列。
資料範圍
1≤n,m≤15輸入樣例:0≤k≤n∗m
2 3 4輸出樣例:10 20 30
40 2 3
oil : 100題解:1 11 2
1 32 1
思路:逐行求解,跟隨當前已經處理的數目, 還有當前行數的左右列座標,還有趨勢
(因為必須是凸的圖形)
需要儲存的狀態:
i 當前處理完的行數
j 已經選出的格仔數
l 當前行已選格仔的左端位置
j 當前行已選格仔的右端位置
x 當前左側輪廓單調型別
y 當前右側輪廓單調型別
記作f[i][j][l][r][x][y]
性質:
左右兩條邊單調性只會變化一次,即由擴張變為收縮
我們由第一行開始dp,如果有j我們用1來表示想左,0來表示向右
左右擴張:
左右擴張情況下,上面i-1行也必然是左右擴張,只需列舉出值最大的段再加上當前l->r的值就好了,即for (int p = l; p <= r; p++) for (int q = p; q <= r; q++) val=max(val,f[i - 1][j - (r - l + 1)][p][q][1][0])
需要注意的是當j==r-l+1
時,即當前行才是圖形的第一行時,不需要計算上一行了
左擴張與右收縮:
剩下的就不過多贅述了
…
#include
#include
#include
using
namespace std;
#define n 16
int n,m,k;
int f[n]
[n*n]
[n][n][2
][2]
;int a[n]
[n];
struct nodeg[n]
[n*n]
[n][n][2
][2]
;int
main()
;}}}
for(
int u=l;u<=r;u++
) vf+
=a[i]
[u];};
}}for(
int u=l;u<=r;u++
) vf+
=a[i]
[u];};
}}for(
int u=l;u<=r;u++
) vf+
=a[i]
[u];};
}}for(
int u=l;u<=r;u++
) vf+
=a[i]
[u];}}
int ans=0;
node t;
for(
int i=
1;i<=n;i++
)for
(int l=
1;l<=m;l++
)for
(int r=l;r<=m;r++
)for
(int x =
0; x <=
1; x ++
)for
(int y =
0; y <=
1; y ++);
}}cout<<
"oil : "
<
while
(t.j)
return0;
}
AcWing 885 求組合數 I
題目描述 給定n組詢問,每組詢問給定兩個整數a,b,請你輸出c a,b mod 10 9 7 的值。輸入格式 第一行包含整數n。接下來n行,每行包含一組a和b。輸出格式 共n行,每行輸出乙個詢問的解。資料範圍 1 n 10000,1 b a 2000 輸入樣例 3 3 15 3 2 2輸出樣例 3 ...
AcWing 753 平方矩陣 I
原題鏈結 題目描述 輸入整數n,輸出乙個n階的回字形二維陣列。陣列的最外層為1,次外層為2,以此類推。輸入格式 輸入包含多行,每行包含乙個整數n。當輸入行為n 0時,表示輸入結束,且該行無需作任何處理。輸出格式 對於每個輸入整數n,輸出乙個滿足要求的n階二維陣列。每個陣列佔n行,每行包含n個用空格隔...
Acwing 905 區間選點
給定n個閉區間 ai,bi 請你在數軸上選擇盡量少的點,使得每個區間內至少包含乙個選出的點。輸出選擇的點的最小數量。位於區間端點上的點也算作區間內。輸入格式 第一行包含整數n,表示區間數。接下來n行,每行包含兩個整數ai,bi 表示乙個區間的兩個端點。輸出格式 輸出乙個整數,表示所需的點的最小數量。...