洛谷P2258 子矩陣

2022-03-17 17:38:27 字數 1264 閱讀 7705

題目

如果暴力的話,時間複雜度是\(rcc(n, n/2)^2\),主要考察搜尋枚舉行和列,並沒有用到dp的思想。

考慮優化的話,發現枚舉行或列中至少需要一步,因為這個題只能預處理優化,如果都不列舉,就相當於盲人摸象,無法預處理來優化。

因此要搜尋枚舉行或列,然後預處理並在列或行上跑dp,這樣就可以少些列舉時間,多些轉移時間。

這裡我用了枚舉行,預處理關於列上的陣列,並在列上跑dp。

預處理和dp陣列如下:

\(dp[i][j]\)表示前\(i\)列,已用\(j\)列得到的最小價值。

\(ver[i]\)表示對於\(i\)列的上下絕對值差的和,\(del[i][j]\)表示\(i\)列和\(j\)列左右差的和

狀態轉移方程:

$dp[i][j] = min(dp[i][j],dp[i-k][j-1]+ver[i]+del[i-k][i]); $

50pts:

#include #include #include #include using namespace std;

int n, m, r, c, dp1[109], dp2[109], a[19][19];

int ans = 0x7fffffff;

void dp()

void dfs(int x, int y, int nr, int nc)

return;

}else

for (int i = x; i <= n; i++) }

int main()

100pts:

#include #include #include #include #include using namespace std;

int n, m, r, c, ans = 2147483647;

int a[19][19], hang[19], dp[19][19];

int ver[19], del[19][19];//ver[i]表示對於i列的上下絕對值差的和,del[i][j]表示i列和j列左右差的和

inline void dp()

void dfs(int now, int pos)

if (pos == n + 1)

return;

for (int i = pos; i <= n; i++)

hang[now] = i, dfs(now + 1, i + 1);

}int main()

洛谷p2258 子矩陣

子矩陣 題目鏈結 然後這是一道非常暴力的題,首先是直接dfs的暴力操作 因為同時枚舉行和列不好列舉,所以我們可以先枚舉行,當行列舉完了,再列舉列。然後都列舉完了,就可以按照題目要求算一下,然後比較算到的答案與當前值的大小,保留較小的那乙個。code includeusing namespace st...

洛谷P2258 子矩陣

給出如下定義 子矩陣 從乙個矩陣當中選取某些行和某些列交叉位置所組成的新矩陣 保持行與列的相對順序 被稱為原矩陣的乙個子矩陣。例如,下面左圖中選取第2 4行和第2 4 5列交叉位置的元素得到乙個2 3的子矩陣如右圖所示。9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 ...

洛谷 P2258 子矩陣

給出如下定義 子矩陣 從乙個矩陣當中選取某些行和某些列交叉位置所組成的新矩陣 保持行與列的相對順序 被稱為原矩陣的乙個子矩陣。例如,下面左圖中選取第22 44行和第22 44 55列交叉位置的元素得到乙個2 times 32 3的子矩陣如右圖所示。9 3 3 3 9 9 4 8 7 4 1 7 4 ...