棋盘型动态规划在二维平面上进行操作。根据当前状态的可能情况做出一个最优的判断,或是依赖当前状态拓展出新的状态,在拓展的过程中,依赖的可能是上一层的最优值也可能是上一层的全部值。
这应该是最容易理解的一种动态规划了,典型例题有数字三角形,比较神的题有方格取数和传纸条
我们这里给出的例子是传纸条问题的简化版,从左上角走到右下角,只能向右或者向下走,每次可以取走所到格子上的数字
问到达终点时所取数字之和的最小值
状态转移方程是很显然的:
f[i][j]=a[i][j]+min(f[i-1][j],f[i][j-1])
但是一定要注意边界的处理,下面给出完整的实现
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int maxn=105; 6 const int INF=0x7f7f7f7f; 7 int n; 8 int a[maxn][maxn],f[maxn][maxn]; 9 int main() 10 { 11 cin>>n; 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 cin>>a[i][j]; 15 for(int i=0;i<=n;i++) 16 f[i][0]=INF; 17 for(int i=0;i<=n;i++) 18 f[0][i]=INF; 19 f[1][0]=f[0][1]=0; 20 for(int i=1;i<=n;i++) 21 { 22 for(int j=1;j<=n;j++) 23 { 24 f[i][j]=a[i][j]+min(f[i-1][j],f[i][j-1]); 25 } 26 } 27 cout<<min(f[n][n-1],f[n-1][n])+a[n][n]<<endl; 28 return 0; 29 }
取最大值我们不怕,最小值一定要关注边界,一定要关注边界,一定要关注边界