1、因为棋子可以往右边或者下边走一步,因此每一个点都可以从他的上边或者左边走过来:
状态转移方程:dp[i][j] = dp[i][j-1]+dp[i-1][j];,表示第i行第j列总共的步数
2、关于马能走到的点和本身的dp要置为0,说明该点的走法为0
3、还有一点很关键:关于边界第0行和第0列,如果在没有马的情况下,除了起点(0,0)dp为0,其他都初始化为1,只能从起点走过来一条路,但是如果有马挡在0行(列)的第j列(行)那么包括该点和之后的该行(列)的dp都应该为0
- # include
- using namespace std;
- int n, m, x, y;
- long long dp[30][30];
- int X[10] = {-1, -2, -2, -1, 1, 2, 2, 1};
- int Y[10] = {-2, -1, 1, 2, 2, 1, -1, -2};
- int ma[30][30];
- int main()
- {
- cin>>n>>m>>x>>y;
- ma[x][y] = 1;
- for (int i=0; i<8; i++)
- {
- int x1 = x+X[i];
- int y1 = y+Y[i];
- if (x1<0||y1<0||x1>n||y1>m)
- continue;
- ma[x1][y1] = 1;
- // cout<
- }
- for (int i=1; i<=n; i++)
- {
- if (ma[i][0])
- break;
- dp[i][0] = 1;
- }
- // cout<
- for (int i=1; i<=m; i++)
- {
- if (ma[0][i])
- break;
- dp[0][i] = 1;
- // cout<
- }
- for (int i=1; i<=n; i++)
- {
- for (int j=1; j<=m; j++)
- {
- if (ma[i][j])
- dp[i][j] = 0;
- else
- dp[i][j] = dp[i-1][j] + dp[i][j-1];
- // cout<
- // cout<
- // cout<
- }
- }
- cout<
-
-
- return 0;
- }
NC16619 传球游戏
题目链接
关键点:
1、首先分析,对于第i次球传到j号手里,那么只能从i-1次的j左右传过来,因此状态转移方程:
dp[i][j] = dp[i-1][j-1]+dp[i-1][j+1],表示第i次球传到j号手里的可能步数
2、初始化,题目要求从1号小蛮开始,因此dp[0][1] = 1;
3、因为是围成一个圈,因此1号是传给2和n号,n号是传给1和n-1号
因此当j-1==0,令其为n
当j+1==n+1,令其为1
完整代码:
- # include
- using namespace std;
- int dp[40][40];//第i次传球,球在j手里
- int n, m;
- int main()
- {
- cin>>n>>m;
- dp[0][1] = 1;
- for (int i=1; i<=m; i++)
- {
- for (int j=1; j<=n; j++)
- {
- int j1 = j-1;
- int j2 = j+1;
- if (j1 == 0)
- j1 = n;
- if (j2==n+1)
- j2 = 1;
- dp[i][j] = dp[i-1][j1]+dp[i-1][j2];
- }
- }
- cout<
1]< - return 0;
- }
NC16810 [NOIP1999]拦截导弹
题目链接
关键点:
1、首先是明确题目要求求的是最长下降子序列,和最长上升子序列
2、一般的dp求最长上升(下降)子序列复杂度为n^2,很明显会超时
3、我们采用贪心+二分,比如求最长上升子序列,我们只要保证该数列的最后一个数尽可能的小,这样给后面的数字留的空间就大了,我们用一个low数组,先初始化为最大值,遍历原数组,对于每一个i,在low数组里找大于等于i的数的位置(lower_bound),放上去,不断更新子序列。然后倒着遍历low数组,哪个位置有数就该位就为答案
4、同样的对于最长下降子序列,我们将原数组倒过来,然后用upper_bound即可
- # include
- using namespace std;
- const int inf = 30000+10;
- int h[100000+10];
- int res[100000+10];
- int low[100000+10];
- int ans1, ans2;
- int main()
- {
- int x, n=0;
- while (cin>>x)
- {
- h[++n] = x;
- }
- for (int i=1; i<=n; i++)
- {
- low[i] = inf;
- }
- for (int i=1; i<=n; i++)
- {
- int dex = lower_bound(low+1, low+1+n, h[i])-low;
- // cout<
- low[dex] = h[i];
- }
- for (int i=n; i>=1; i--)
- {
- if (low[i]!=inf)
- {
- ans2 = i;
- break;
- }
- }
-
- for (int i=n; i>=1; i--)
- res[i] = h[n-i+1];
- for (int i=1; i<=n; i++)
- {
- low[i] = inf;
- }
- for (int i=1; i<=n; i++)
- {
- int dex = upper_bound(low+1, low+1+n, res[i])-low;
- // cout<
- low[dex] = res[i];
- }
- for (int i=n; i>=1; i--)
- {
- if (low[i]!=inf)
- {
- ans1 = i;
- break;
- }
- }
- cout<
- return 0;
- }
-
相关阅读:
概率论与数理统计
基于微信小程序的火锅店点餐订餐系统设计与实现(源码+lw+部署文档+讲解等)
docker基础篇:安装tomcat
【560. 和为 K 的子数组】
ros之乌龟做圆周运动and订阅乌龟的位姿信息
行行AI人工智能大会 | LTD荣获“AI强应用创新TOP50代表企业”
Linux开发——Makefile 基础(九)
Vue:生命周期(从出生到销毁)
Python 网络请求工具库
关于 Python 的经典入门书籍有哪些?
-
原文地址:https://blog.csdn.net/m0_60531106/article/details/126594038