马走日 DP

 附上题目链接:https://ac.nowcoder.com/acm/contest/301/F

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define mod 1000000007
using namespace std;
long long dirx[]={0,1,2,2,1,-1,-2,-2,-1};
long long diry[]={0,-2,-1,1,2,2,1,-1,-2};
long long n,m,step;
long long dp[210][210][210];
int main()
{
    while(cin>>n>>m>>step)
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][0]=1;//初始只有一种方法可以到达
    for(int i=1;i<=step;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int k=0;k<m;k++)
            {
                for(int l=1;l<=8;l++)
                {
                    if(j+dirx[l]>=0 && k+diry[l]>=0 && j+dirx[l]<n && k+diry[l]<m)
                    dp[j+dirx[l]][k+diry[l]][i]=(dp[j+dirx[l]][k+diry[l]][i]+dp[j][k][i-1])%mod;//当前在(j,k)位置,如果有方法走到(j+dirx[l],k+diry[l])位置,就把走到位置
//dp[j][k]的方案数加上去,dp[j+dirx[l]][k+diry[l]][i]也要加是因为可能有别的位置也能到达
                }
            }
        }
    }
    printf("%lld\n",dp[n-1][m-1][step]);
    }
     
    return 0;
}
//这个裸的DFS不知道为什么一直超时,不知道怎么剪枝



#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int n,m,k,ans;
int vst[209][209];
int move1[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
void dfs(int x,int y,int count){
    if(count>k) return;
    for(int i=0;i<8;i++){
        count++;
        x+=move1[i][0];
        y+=move1[i][1];
        if(x==n-1&&y==n-1){
            ans++;
            ans=ans%1000000007;
            return ;
        }
        if(x<=n&&y<=m&&x>=0&&y>=0&&vst[x][y]==0){
            vst[x][y]=1;
            dfs(x,y,count);
        }else{
            return ;
        }
        vst[x][y]=0;
        count--;
    }
}
 
int main(){
    while(~scanf("%d %d %d",&n,&m,&k)){
        ans=0;
        for(int i=0;i<200;i++){
            for(int j=0;j<200;j++){
                vst[i][j]=0;
            }  
        }
        dfs(0,0,0);
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/StarrYooSkY/article/details/84711102