首页 > 其他分享 >P1002 [NOIP2002 普及组] 过河卒

P1002 [NOIP2002 普及组] 过河卒

时间:2023-09-26 16:34:15浏览次数:32  
标签:过河 数组 NOIP2002 int P1002 && my mx dp

P1002 [NOIP2002 普及组] 过河卒

基础DP

卒只能向右/向下

由此可得转移方程

dp[i][j] = dp[i -1][j] + dp[i][j - 1]

卒不能走马能到的地方和马所在的地方

则用一个数组标记马能到的地方和马所在的地方,在经过该点的时候跳过即可

注意判断边界问题以及dp数组的初始化

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n"
typedef pair<int, int> PII;

const int N = 40;

int fx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int fy[] = {1, 2, 2, 1, -1, -2, -2, -1};
// 马能走到的位置
int dp[N][N];
// dp数组
bool s[N][N];
// 标记
int bx, by, mx, my;

void solve()
{
    cin >> bx >> by >> mx >> my;
    s[mx][my] = true;	// 马在的地方不能走
    for (int i = 0; i < 8; i++) {
        if (mx + fx[i] >= 0 && my + fy[i] >= 0) s[mx + fx[i]][my + fy[i]] = true;
    }
    // 这里判断边界,可能出现0 - 2这种情况,数组会越界
    if (!s[1][0]) dp[1][0] = 1;
    if (!s[0][1]) dp[0][1] = 1;
    // 不赋初值则dp[i][j]始终为0,还需判断第一次向右/向下能不能走,能走再赋初值(这两个点可能不能走)
    for (int i = 0; i <= bx; i++) {
        for (int j = 0; j <= by; j++) {
            if (s[i][j]) continue;	// 标记有马,不能走
            if (i - 1 >= 0 && j - 1 < 0 && dp[i - 1][j]) dp[i][j] = dp[i - 1][j];
            else if (i - 1 < 0 && j - 1 >= 0 && dp[i][j - 1]) dp[i][j] = dp[i][j - 1];
            else if (i - 1 >= 0 && j - 1 >= 0) dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            // 判断边界,防止数组越界
            // 关于判断数组非空,因为前面赋初值的地方可能为0,然后就导致dp[1][1]为0,就寄了
            // 望指正
        }
    }
    cout << dp[bx][by] << endl;
}

signed main()
{

    ios;
    int T = 1;
    //cin >> T;
    while(T--)
    {
        solve();
    }
    return 0;
}

标签:过河,数组,NOIP2002,int,P1002,&&,my,mx,dp
From: https://www.cnblogs.com/ysqfirmament/p/17730389.html

相关文章

  • 【题解】洛谷 P1002 [NOIP2002 普及组] 过河卒
    原题链接解题思路这是一道经典的动态规划题目。如果尝试使用深度优先搜索(dfs)或广度优先搜索(bfs)做就会获得TLE(注意数据范围)。于是我们想到了更为高级的动态规划(DynamicProgramming,dp)。简略介绍动态规划算法的核心思想:把原问题分解为相对简单的子问题的方式求解复杂问题。......
  • P9169-过河卒
    原题链接过河卒题目大意一个\(n\timesn\)的棋盘,上有一黑二红三子,黑棋每次可以从\((x,y)\)移动到\((x-1,y),(x,y-1),(x,y+1)\),红棋每次可以从\((x,y)\)移动到\((x-1,y),(x+1,y),(x,y-1),(x,y+1)\),求双方都使用最优策略的情况下谁最少要几步获胜。某一方获胜当且仅当:......
  • 「NOIP2002」均分纸牌
    ​题目描述有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆......
  • 士兵过河
    题目描述一支个士兵的军队正在趁夜色逃亡途中遇到一条湍急的大河敌军在的时长后到达河面,没到过对岸的士兵都会被消灭。现在军队只找到了只小船,这船最多能同时坐上个士兵。当个土兵划船过河,用时为当个士兵坐船同时划船过河时,用时为两土兵中用时最长的.当个士兵坐船个士兵划船时,用......
  • 2023-08-06:小青蛙住在一条河边, 它想到河对岸的学校去学习 小青蛙打算经过河里 的石头
    2023-08-06:小青蛙住在一条河边,它想到河对岸的学校去学习小青蛙打算经过河里的石头跳到对岸河里的石头排成了一条直线,小青蛙每次跳跃必须落在一块石头或者岸上给定一个长度为n的数组arr,表示每块儿石头的高度数值每块石头有一个高度,每次小青蛙从一块石头起跳这块石头的高度就......
  • 2023-08-06:小青蛙住在一条河边, 它想到河对岸的学校去学习 小青蛙打算经过河里 的石头
    2023-08-06:小青蛙住在一条河边,它想到河对岸的学校去学习小青蛙打算经过河里的石头跳到对岸河里的石头排成了一条直线,小青蛙每次跳跃必须落在一块石头或者岸上给定一个长度为n的数组arr,表示每块儿石头的高度数值每块石头有一个高度,每次小青蛙从一块石头起跳这块石头的......
  • P1002 [NOIP2002 普及组] 过河卒 入门级别的dp
     思路:1.标记马点z[i][[j]=02.正常z[i][j]=z[i-1][j]+z[i][j-1]#include<iostream>usingnamespacestd;intn,m,a,b;longlongma[30][30],bck[30][30];intdx[8]={-2,-1,1,2,2,1,-1,-2},dy[8]={1,2,2,1,-1,-2,-2,-1};voidcan_not_reach(intx,inty){ma[......
  • 5944: 小船过河 经典贪心
    描述  N个人要过河,但只有一条小船,每次只能坐2人,每个人有不同的划船速度,而两个人一起过河时小船速度由最慢的人的速度决定。请设计一个过河方案,使得所有人均过河,且所用总时间最少。   输入  第一行为正整数N(N<=1000),表示人数,第二行为N个正整数,表示每个人的速度(......
  • 【搜索】 FZU 2188 过河I
    bfs搜索,x,y和船停的地方。#include<iostream>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<cstdio>#include<algorithm>#include<cstring>#include<climits>......
  • [NOIP2002 提高组] 均分纸牌
    题目描述有\(N\)堆纸牌,编号分别为\(1,2,\ldots,N\)。每堆上有若干张,但纸牌总数必为\(N\)的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为\(1\)堆上取的纸牌,只能移到编号为\(2\)的堆上;在编号为\(N\)的堆上取的纸牌,只能移到编号为\(N-1\)的堆上;其他......