题目:CodeVS 1010
如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和
C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C不等于A,同时C不等于B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。
INPUT:
6 6 3 2
OUTPUT:
17
********************************************华丽丽的分割线*************************************************
比昨天更加理解了一些DP,又看知乎上的大神们的讲解又是查算法导论的...
其实DP算法吧 就是为了使解决问题得更加迅速 而将之前的算过的可用结果储存起来而已。“站在巨人的肩膀上” 大概说的就是它吧
大多数DP都是用数组储存 根据题目需要开出几维 然后通过几层循环按照某种顺序递推出某一时间点的解
今天跟同学探讨了01背包和完全背包...emmm感觉不错
不过学习是一个循序渐进的过程,所以选择了CodeVS的题库(主要是已经分好了类)进行动态规划专题的练习。
一道一道地做 这道题虽然水但也用到了递推的思想(不知道这题跟DP有什么关系我觉得跟排列组合关系更大)
完整代码:
#include <iostream> #include <cstring> using namespace std; int map[31][31];long long f[31][31]; const int gx[8]={2,2,1,-1,-2,-2,-1,1}; const int gy[8]={1,-1,-2,-2,-1,1,2,2}; int main() { memset(map,0,sizeof(map)); memset(f,0,sizeof(f)); int n,m,cx,cy; cin>>n>>m>>cx>>cy; map[cx][cy]=1; for(int i=0;i<8;i++){ map[cx+gx[i]][cy+gy[i]]=1; } f[0][0]=1; for(int i=0;i<=n;i++){ for(int j=0;j<=m;j++){ if(map[i+1][j]==0)f[i+1][j]+=f[i][j]; if(map[i][j+1]==0)f[i][j+1]+=f[i][j]; } } cout<<f[n][m]<<endl; return 0; }
其实一开始递推式写的是
1 f[0][0] = 1; 2 for (int i = 0;i <= n; ++i) { 3 for (int j = 0; j <= m; ++j) { 4 if (i != 0) { 5 f[i][j] = f[i][j] + f[i-1][j]; 6 } 7 if (j != 0) { 8 f[i][j] = f[i][j] + f[i][j-1]; 9 } 10 } 11 }
可是呢 好像出了点问题 计算结果总出1...于是看了题解换汤不换药地把递推式由计算当前位置改成了计算下一个位置...
然后过了...过了...
程序设计真是个神奇的东西啊