下午刚来集训,在题库里刷了四道题,第一道题和第二道题都比较基础,第三道题还挺有意思的,跟大家分享一下。
这是一道动态规划题,可以根据样例模拟一下 , 就可以求出状态转移方程了。
步骤大概是这样的:A点 , B点,M是马的位置,X是被马拦着不能走的点(别告诉我你们连马走"日"字都不知道)
其中每个点的值代表的是从A点走到这个位置需要用多少步
这样很容易能看出来
关于 f[i][j] 这个点 , 从(0,0)位置到 B 点 , 会经过他这个点的路线有
f[1][1]=1
f[i][j] = f[i-1][j] + f[i][j-1]
但是这个方程是推不出结果的 , 因为这样A点会在一开始的时候被覆盖成0
所以修改以后的方程就是
f[1][1]=1
f[i][j] = max( f[i-1][j] + f[i][j-1] , f[i][j] )
当然还有不用max 的转移方程
f[1][0] = 1
ff[i][j] = f[i-1][j] + f[i][j-1]
f[1][1] 这个点通过从 f[1][0]这个点直接转移过来
因为转移方程的时候需要 i-1和 j-1所以如果不从 1开始就会因数组越界而 WA一个点
从 1开始就是把每个点的坐标都加了 1而已
另外这道题的标签里有高精
题目说明也写着结果可能很大!但是 unsigned long 就可以过去
我的AC源代码:
#include <iostream>
#include <algorithm>
using namespace std;
int a[30][30];
unsigned long long f[30][30];
void horse(int x,int y)
{
a[x][y]=1;
a[x-1][y-2]=1;
a[x+1][y-2]=1;
a[x-1][y+2]=1;
a[x+1][y+2]=1;
a[x-2][y-1]=1;
a[x+2][y-1]=1;
a[x-2][y+1]=1;
a[x+2][y+1]=1;
}
int main(int argc, char** argv) {
int x,y,m,n;
cin>>x>>y>>n>>m;
x++;y++;n++;m++;
horse(n,m);
f[1][1]=1;
for(int i=1;i<=x;i++)
for(int j=1;j<=y;j++){
if(a[i][j]) continue;
f[i][j]=max(f[i][j],f[i-1][j]+f[i][j-1]);
}
cout<<f[x][y];
return 0;
}