1. 程式人生 > >hiho150周 - 動態規劃*

hiho150周 - 動態規劃*

得來 targe pac cnblogs int def spa blog efi

題目鏈接

一個n*m的迷宮由‘.’和‘b‘組成,從(1,1)走到(n,m),只能向右或者向下走,但遇到‘b’時才能改變方向,開始時方向向右。

問到達(n,m)至少改變幾個位置上的值

/***********************************************************/

原來轉移方程也可以這麽優美

每個方格有兩個狀態,向右和向下

這兩個狀態均由左邊和上邊的兩個方格四個狀態轉移得來

#include <set>
#include <map>
#include <stack>
#include <queue>
#include 
<cmath> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define MAX(a,b) ((a)>=(b)?(a):(b)) #define MIN(a,b) ((a)<=(b)?(a):(b)) #define long long LL #define OO 0x0fffffff using
namespace std; #define RIGHT 0 #define DOWN 1 const int N = 111; char maze[N][N]; int dp[N][N][2]; int main(){ int n,m; cin>>n>>m; for(int i=0;i<n;i++) cin>>maze[i]; for(int i=0;i<n;i++) maze[i][m] = b; for(int j=0;j<m;j++) maze[n][j] = b; dp[0][0
][0] = (maze[0][0]==b); dp[0][0][1] = (maze[0][0]==b)+(maze[0][1]!=b); for(int i=0;i<n;i++) for(int j=0;j<m;j++){ if(!(i+j)) continue; dp[i][j][0] = dp[i][j][1] = OO; if(j-1>=0){ dp[i][j][0] = MIN(dp[i][j-1][0],dp[i][j-1][1]+(maze[i+1][j-1]!=b)); dp[i][j][1] = MIN(dp[i][j-1][0]+(maze[i][j+1]!=b),dp[i][j-1][1]+(maze[i+1][j-1]!=b)+(maze[i][j+1]!=b)); } if(i-1>=0){ dp[i][j][0] = MIN(dp[i][j][0],dp[i-1][j][0]+(maze[i-1][j+1]!=b)+(maze[i+1][j]!=b)); dp[i][j][0] = MIN(dp[i][j][0],dp[i-1][j][1]+(maze[i+1][j]!=b)); dp[i][j][1] = MIN(dp[i][j][1],dp[i-1][j][0]+(maze[i-1][j+1]!=b)); dp[i][j][1] = MIN(dp[i][j][1],dp[i-1][j][1]); } dp[i][j][0]+=(maze[i][j]!=.); dp[i][j][1]+=(maze[i][j]!=.); } printf("%d\n",MIN(dp[n-1][m-1][0],dp[n-1][m-1][1])); return 0; }

hiho150周 - 動態規劃*