https://www.luogu.org/problem/P1002

题目描述

如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。
棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C不等于A,同时C不等于B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。。

输入描述:

输入B点的坐标(n,m)以及对方马的坐标(X,Y){不用判错}

输出描述:

输出一个整数(路径的条数)。

示例1

输入

   

输出


说明/提示

结果可能很大!

一开始按DFS做,超时

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const double PI=acos(-);
const int maxn=;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); int n,m,x,y;
int ans; bool judge(int a,int b)
{
if(a==x&&b==y)
return false;
if(a==x-&&b==y-)
return false;
if(a==x-&&b==y-)
return false;
if(a==x+&&b==y-)
return false;
if(a==x+&&b==y-)
return false;
if(a==x-&&b==y+)
return false;
if(a==x+&&b==y+)
return false;
if(a==x-&&b==y+)
return false;
if(a==x+&&b==y+)
return false;
return true;
} void DFS(int a,int b)
{
if(a==n&&b==m)
{
ans++;
return ;
}
if(a+<=n&&judge(a+,b))
DFS(a+,b);
if(b+<=m&&judge(a,b+))
DFS(a,b+);
} int main()
{
scanf("%d %d %d %d",&n,&m,&x,&y);
DFS(,);
printf("%d\n",ans);
return ;
}

后来以为if判断太多,换了种方法,依然超时

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const double PI=acos(-);
const int maxn=;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); int n,m,x,y;
int G[][];
int ans; void DFS(int a,int b)
{
if(a==n&&b==m)
{
ans++;
return ;
}
if(a+<=n&&G[a+][b]==)
DFS(a+,b);
if(b+<=m&&G[a][b+]==)
DFS(a,b+);
return ;
} int main()
{
//freopen("testdate.in","r",stdin);
scanf("%d %d %d %d",&n,&m,&x,&y);
G[x][y]=;
if(x->=)
{
G[x-][y-]=;
G[x-][y+]=;
}
if(y->=)
{
G[x-][y-]=;
G[x+][y-]=;
}
if(x->=)
{
G[x-][y+]=;
}
if(y->=)
{
G[x+][y-]=;
}
G[x+][y+]=;
G[x+][y+]=;
DFS(,);
printf("%d\n",ans);
return ;
}

最后意识到,这题没那么简单.

看过题解才明白这题是记忆化递推,或者说是DP

DP题就是要找到状态转移方程,这题的状态转移方程只用手动模拟一下就可以了,就可以得出到每一个点的方案数就是上面和左边的方案数的总和(因为只可以向右走或向下走),具体的状态转移方程是

即可以写成DP[i][j]=max(DP[i][j],DP[i-1][j]+DP[i][j-1])

注意,最大的结果已经超过了int的范围,这是一个坑

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const double PI=acos(-);
const int maxn=;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); int n,m,x,y;
LL DP[][];//DP[i][j]代表从A点到(i,j)的线路条数
bool G[][];//判断这个点有没有马盯着
//马可以走到的位置
int fx[]={,-,-,,,,,-,-};
int fy[]={,,,,,-,-,-,-}; int main()
{
scanf("%d %d %d %d",&n,&m,&x,&y);
n+=;m+=,x+=,y+=;//坐标加2,防止标记马时越界
for(int i=;i<=;i++)//标记马的位置
{
G[x+fx[i]][y+fy[i]]=true;
}
DP[][]=;//初始化
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(G[i][j])
continue;
DP[i][j]=max(DP[i][j],DP[i-][j]+DP[i][j-]);//状态转移方程
}
}
printf("%lld\n",DP[n][m]);
return ;
}

下面粘一个有意思的代码(递推):

我们可以发现一个规律:每个数都等于它上面左边的数的和

 #include <iostream>
using namespace std; int n,m,my,mx;
long long a[][]; int main()
{
cin >>n >>m >>my >>mx;//输入数据
n=n+;m=m+;my=my+;mx=mx+; //隔出两格,当要把马可跳到的地方掷成0时不会出错
for(int z=;z<=m;z++)
{
for(int y=;y<=n;y++)
{
a[z][y]=a[z-][y]+a[z][y-]; //将这个数左边和上面的数相加
a[][]=;//由于会把起点掷成0,所以要回归1
a[mx][my]=;//将马的地方掷成0
a[mx+][my+]=;a[mx+][my-]=;//将马可跳到的地方掷成0
a[mx-][my+]=;a[mx-][my-]=;//将马可跳到的地方掷成0
a[mx+][my+]=;a[mx+][my-]=;//将马可跳到的地方掷成0
a[mx-][my+]=;a[mx-][my-]=;//将马可跳到的地方掷成0
}
}
cout <<a[m][n];//输出结果
return ;
}

NOIP2002 过河卒(DFS,DP)的更多相关文章

  1. SDUT 1265-马停下过河卒(DFS)

    马拦过河卒 nid=24#time" title="C.C++.go.haskell.lua.pascal Time Limit3000ms Memory Limit 65536K ...

  2. 洛谷P1002 过河卒【dp】

    棋盘上AA点有一个过河卒,需要走到目标BB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过河卒 ...

  3. NOIP 2002过河卒 Label:dp

    题目描述 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例如 ...

  4. P1002 过河卒【dp】

    P1002 过河卒 题目描述 棋盘上AAA点有一个过河卒,需要走到目标BBB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CCC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制 ...

  5. 洛谷 - P1002 - 过河卒 - 简单dp

    https://www.luogu.org/problemnew/show/P1002 方程很好想,题目也很暴力.感谢题目提示数据会很大. #include<bits/stdc++.h> ...

  6. 过河卒(Noip2002)(dp)

    过河卒(Noip2002) 时间限制: 1 Sec  内存限制: 128 MB提交: 7  解决: 6[提交][状态][讨论版][命题人:quanxing] 题目描述 棋盘上A点有一个过河卒,需要走到 ...

  7. dp练习(4)——过河卒

    1010 过河卒 2002年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 如图,A ...

  8. 【openjudge】【递推】例3.6 过河卒(Noip2002)

    [题目描述] 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1 ...

  9. 过河卒 NOIp 2002 dp

    题目描述 棋盘上AAA点有一个过河卒,需要走到目标BBB点.卒行走的规则:可以向下.或者向右.同时在棋盘上CCC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦 ...

随机推荐

  1. 关于torch.nn.Linear的笔记

    关于该类: torch.nn.Linear(in_features, out_features, bias=True) 可以对输入数据进行线性变换: $y  = x A^T + b$ in_featu ...

  2. 关于indexOf的用法

     var fullTaskName = this.form.taskName;       var index=fullTaskName.lastIndexOf("-");     ...

  3. 安装postgresql后找不到服务 postgresql service

    问题再现 环境: postgresql: 11.5 windows 10 企业版LTSC 64位 使用postgresql-11.5-1-windows-x64.exe安装后,让重新启动,但是重启后, ...

  4. PAT A1018

    A 1018 Public Bike Management 这个题目算是比较典型的一个.我分别用dfs,及dijkstra+dfs实现了一下. dfs实现代码: #include <cstdio ...

  5. {转}理解HTTP/304响应

    源文(英):http://www.telerik.com/blogs/understanding-http-304-responses 中文译文:http://www.cnblogs.com/ziyu ...

  6. 吴裕雄--天生自然MySQL学习笔记:MySQL NULL 值处理

    MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. 为了处理这种情况,MySQL提供了三大运算符 ...

  7. 吴裕雄--天生自然 JAVASCRIPT开发学习: HTML DOM - 改变CSS

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Cpp:"->"和"."的区别

    environments:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) class data{ publi ...

  9. javaweb04 ServletRequest&ServletResponse

    WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个歌规则就是 HTTP协议HTTP协议是超文本传输协议,它是TCP/IP协议集中的一个应用层协议,用于定义WEB浏览器与WEB服 ...

  10. webpack4+vue 打包 就是没效果?求解!!!

    开始对着视频操作 教学视频 用的webpack2 所以没成功  但是 Jquery 可以 成功渲染.Vue就不行. 百度 webpack4+vue打包简单入门:https://segmentfault ...