zoukankan      html  css  js  c++  java
  • luogu1002 题解

    希望大家都没有忘记,小学时老师曾讲过这样一个问题:

    ···
    · · ·
    · · ·

    如图,小明家在图中的最左下角,学校在最右上角,请问:小明有多少种最短的方法到达学校?

    那么老师讲,这个问题的解法是这样的:

    136
    1 2 3
    0 1 1

    像这样逐个标点,将原点上方和右方全部标为1,其他的格子都是它的左边一个和下边一个点上数字的和,由此计算出方法数。

    而这个,正是我们学习的一大难点————动态规划。

    真没想到,小学老师竟然讲过动态规划!

    那么,这道题也是类似,只是加上了障碍。

    话不多说,直接上题解。

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 int n, m;//地图长宽
      6 
      7 long long a[25][25];//定义地图
      8 
      9 int horse_dirx[9] = {0,1,-1,1,-1,2,2,-2,-2};
     10 
     11 int horse_diry[9] = {0,2,2,-2,-2,1,-1,1,-1};//定义马的走向
     12 
     13 void setmap(int x, int y)//标记地图,预处理
     14 
     15 {
     16 
     17     int i;
     18 
     19     a[0][0] = 0;//起点不可走
     20 
     21     a[x][y] = 0;//马的位置不可走
     22 
     23     bool p = true;//判断横向纵向能否走到
     24 
     25     for (i = 1;i <= 8; i ++)
     26 
     27     {
     28 
     29         int nx = x + horse_dirx[i], ny = y + horse_diry[i];
     30 
     31         if(nx >= 0 && ny >= 0 && nx <= n && ny <= m)
     32             a[nx][ny] = 0;
     33 
     34     }//标记马的控制点,不可走
     35 
     36     for (i = 1; i <= m; i ++)
     37 
     38     {
     39 
     40         if(a[0][i] == -1)
     41 
     42         {
     43 
     44             if (p == true) a[0][i] = 1;
     45 
     46             else a[0][i] = 0;
     47 
     48         }
     49 
     50         else p = false;
     51 
     52     }//横向判断
     53 
     54     p = true;//重置变量
     55 
     56     for ( i = 1; i <= n; i ++)
     57 
     58     {
     59 
     60         if(a[i][0] == -1)
     61 
     62         {
     63 
     64             if (p == true)a[i][0] = 1;
     65 
     66             else a[i][0] = 0;
     67 
     68         }
     69 
     70         else p = false;
     71 
     72     }//纵向判断
     73 
     74 }
     75 
     76 int main()
     77 
     78 {
     79     ios :: sync_with_stdio(false)//输入输出优化
     80 
     81     memset (a,-1,sizeof(a));
     82 
     83     int i, j, x, y;
     84 
     85     cin >> n >> m >> x >> y;
     86 
     87     setmap(x, y);//定义、预处理
     88 
     89     for (i = 0; i <= n; i ++)
     90 
     91         for (j = 0; j <= m; j ++)
     92 
     93             if (a[i][j] == -1)
     94 
     95                 if (i != 0 && j != 0)a[i][j] = a[i-1][j] + a[i][j-1];//标记
     96 
     97     //  for (i = 0; i <= n; i ++)
     98 
     99     //  {
    100 
    101     //      for (j = 0; j < m; j ++)
    102 
    103     //          cout << a[i][j] << " ";
    104 
    105     //      cout << a[i][j] << endl;
    106 
    107     //  }检查时输出
    108 
    109     cout << a[n][m] << endl;
    110 
    111     return 0;
    112 }

    另一种思路:

    #include<iostream>
    #define L(i,k,mx,my) (i==mx+1||i==mx-1)&&(k==my+2||k==my-2)       
    using namespace std;
    int mx,my,m,n;
    long long f[30][30]={1};           
    bool li(int i,int k){
        if(i==mx&&k==my||i==0&&k==0) return 1;
        if(L(i,k,mx,my)||L(k,i,my,mx)) return 1;
        return 0;
    }               
    int main(){    
        cin>>n>>m>>mx>>my;
        for(int i=0;i<=n;i++)
            for(int k=0;k<=m;k++)
                if(!li(i,k)) f[i][k]=f[i][k==0? k:k-1]+f[i==0? i:i-1][k];         
        cout<<f[n][m];
        return 0;
    } 

    部分选自luogu 题解。

  • 相关阅读:
    Linux下多进程编程消息队列
    Linux下多线程编程之——线程专有数据
    Linux下多线程编程之——线程互斥
    Linux下多线程编程之——线程竞争
    Linux下多线程编程之——线程取消
    Linux下多线程编程之——线程分离
    Linux下多线程编程之——多线程委托模型
    Postman 提交测试的时候提示 Bad Request
    Confluence 6 其他页面操作和页面大小
    Confluence 6 页面的组织和移动概述
  • 原文地址:https://www.cnblogs.com/wangshengjun/p/luoguP1002.html
Copyright © 2011-2022 走看看