过河卒:https://www.luogu.com.cn/problem/P1002
思路:
主要还是要明确状态转移方程: f1[i][j] = max( f1[i][j] , f1[i-1][j] + f1[i][j-1] );
即每一个地方的路线数是当前格子的上一个格的数字加左边那个格子的数字。
#include <iostream>
#include <iomanip>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#define ull unsigned long long
using namespace std;
//马要走的8个位置
const int fx[] = {0, -2, -1, 1, 2, 2, 1, -1, -2};
const int fy[] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
//马可以走到的位置
int bx,by;//b的位置
int mx,my;//马的位置
ull f[30];//f[j]代表从每一行的第一个点到(j)点会经过的线路数
ull f1[30][30];//f[i][j]代表从A点到(i,j)会经过的线路数
bool s[30][30];//判断这个点有没有马盯着
int main(){
scanf("%d%d%d%d", &bx, &by, &mx, &my);
bx += 2; by += 2; mx += 2; my += 2;//坐标+2以防越界
f[2] = 1;//初始化
//f1[2][2] = 1;//初始化
s[mx][my] = 1;//标记马的位置
for(int i = 1; i <= 8; i++)//标记马的可达的地方
s[ mx + fx[i] ][ my + fy[i] ] = 1;
//方法一:
// for(int i = 2; i <= bx; i++){//列
// for(int j = 2; j <= by; j++){//行
// if(s[i][j])continue;//若是马占据了则跳过
// f1[i][j] = max( f1[i][j] , f1[i - 1][j] + f1[i][j - 1] );//状态转移方程
// }
// }
//方法二:滚动数组
for (int i = 2; i<=bx; i++) {
for (int j = 2; j<=by; j++) {
if(s[i][j]){
f[j] = 0;//若是马占据了则跳过
//printf("%d ",f[j]);
continue;
}
f[j] = f[j]+f[j-1];
//printf("%d ",f[j]);
}
//printf("==========\n");
}
printf("%llu\n", f[by]);
return 0;
}