\(s\) 國的動物園是乙個 \(n\times m\) 的網格圖,左上角的座標是 \((1,1)\),右下角的座標是 \((n,m)\)。
小象在動物園的左上角,它想回到右下角的家裡去睡覺,但是動物園中有一些老鼠,而小象又很害怕老鼠。動物園裡的老鼠是彼此互不相同的。小象的害怕值定義為他回家的路徑上可以看見的不同的老鼠的數量。若小象當前的位置為 \((x_1,y_1)\),小象可以看見老鼠,當且僅當老鼠的位置 \((x_2,y_2)\) 滿足 \(|x_1-x_2|+|y_1-y_2|\leq 1\) 。
由於小象很睏了,所以小象只會走一條最近的路回家,即小象只會向下或者向右走。現在你需要幫小象確定一條回家的路線,使得小象的害怕值最小。
第一行包含兩個用空格隔開的整數,\(n\) 和 \(m\)。
接下來乙個 \(n\times m\) 的矩陣表示動物園的地圖。其中 \(a[i][j]\) 表示第i行第j列上老鼠的數量。
若 \(a[i][j]=0\) 則表示當前位置上沒有老鼠(小象的家裡也可能存在老鼠)。
輸出乙個整數,表示路線最小的害怕值是多少。
3 9
0 0 1 0 0 0 0 0 1
1 1 1 1 1 1 0 1 0
1 0 0 1 0 0 1 0 0
9
對於 \(10\%\) 的資料,\(1\leq n,m\leq 5\)。
對於 \(100\%\)的資料,\(1\leq n,m\leq 1000,0\leq a[i][j]\leq100\)。
一開始我們發現是乙個棋盤形的圖,我們可以考慮暴力走 \(dfs\),但是有乙個限制,看過的老鼠就無法再次計數了,所以直接掃的話比較麻煩。
因為我們可以發現小象只可以往下和往右走,所以就可以定義 \(dp[i][j][1/0]\),表示小象在 \(a[i][j]\) 的位置時,上一步向下或向右走到當前位置,所見到的老鼠的最小值,這樣我們就可以從上一列或上一行轉移過來。
同時,我們在計算的同時注意不要重複計數即可。
動態轉移方程:
/*0表示從上面走來,1表示從左面走來*/
f[i][j][0]=min(f[i][j][0],f[i-1][j][0]+pan[i][j-1]+pan[i][j+1]+pan[i+1][j]);//上一步也從上面走來
f[i][j][0]=min(f[i][j][0],f[i-1][j][1]+pan[i+1][j]+pan[i][j+1]);//上一步從左面走來
f[i][j][1]=min(f[i][j][1],f[i][j-1][1]+pan[i-1][j]+pan[i][j+1]+pan[i+1][j]);//上一步也從左面走來
f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+pan[i][j+1]+pan[i+1][j]);//上一步從上面走來
#includeusing namespace std;
const int maxn=1e3+50;
int n,m;
int pan[maxn][maxn];
int f[maxn][maxn][2];
int main()
} memset(f,0x3f,sizeof(f));
f[1][1][1]=pan[1][1]+pan[1][2]+pan[2][1];//初始化
f[1][1][0]=f[1][1][1];
for(int i=1;i<=n;i++)
} printf("%d\n",min(f[n][m][1],f[n][m][0]));
return 0;
}
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...
DP基礎(線性DP)總結
前言 雖然確實有點基礎.但凡事得腳踏實地地做,基礎不牢,地動山搖,嗯!dp方程 dp i max 複雜度 o n 2 法一 資料結構無腦暴力優化 以a i 為陣列下標,從1到a i 訪問最大值,再加一,進行更新 法二 設h k 表示dp值為k的最長上公升子串行的最小值 有點貪心在裡面 顯然h k h...
線性DP 餅乾
第一次做這種處理方法的dp,這道題我們是先在乙個大的可行方案集合中確定乙個小的子集,這個子集也滿足這個方案。我們根據排序不等式 可以自己查一下,證明過程很簡單。可以知道,如果乙個序列式g ig i gi 是公升序的。a ia i ai 是降序的。那麼我們ai gi a i g i ai gi 的和一...