初识动态规划

1.确定dp数组dp table)以及下标的含义

2.确定递推

3.dp数组如何初始化

4.确定遍历顺序

5.举例推导dp数组

我们在写动态规划的时候,就是写这几步,一步一步来就ok;而不是一个简简单单的递归公式

比如我们求斐波拉契数列就是,数组下标含义是第几个数,递归公式为一个数是前2个的数的和,数组的初始化就是第0个数是0,第一个数是1,那我们是前面几个那便利顺序就应该是从前往后,然后就可以把这个写出来

a[0]=0;
a[1]=1;
for(i=2;i<=n;i++)
{
    a[i]=a[i-1]+a[i-2];
}

题目

# [NOIP2002 普及组] 过河卒

## 题目描述

棋盘上 $A$ 点有一个过河卒,需要走到目标 $B$ 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 $C$ 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,$A$ 点 $(0, 0)$、$B$ 点 $(n, m)$,同样马的位置坐标是需要给出的。

![](https://cdn.luogu.com.cn/upload/image_hosting/vg6k477j.png)

现在要求你计算出卒从 $A$ 点能够到达 $B$ 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

## 输入格式

一行四个正整数,分别表示 $B$ 点坐标和马的坐标。

## 输出格式

一个整数,表示所有的路径条数。

## 样例 #1

### 样例输入 #1

```

6 6 3 3

```

### 样例输出 #1

```

6

```

## 提示

对于 $100 \%$ 的数据,$1 \le n, m \le 20$,$0 \le$ 马的坐标 $\le 20$。

**【题目来源】**

NOIP 2002 普及组第四题

我们按照上面5步来,下标含义是该点的位置,递归公式为fa[i][j]=fa[i-1][j]+fa[i][j-1];初始化应该就是fa【1】【1】就是1,我们从1,1开始方便一些,遍历数组是前面两个推出后面的,那遍历就应该是从前往后,按照着几步,把代码写出来就ok

#include <stdio.h>
long long fa[100][100];//棋盘0就是ok,1就是不ok
int pan[100][100];
int ma[9]={0,1,2,2,1,-1,-2,-2,-1};//x坐标
int ma1[9]={0,2,1,-1,-2,-2,-1,1,2};//y坐标
int main()
{
    int i,j;
    int n,m,x,y;
    scanf("%d%d%d%d",&n,&m,&x,&y);//坐标
    n+=2;m+=2;x+=2;y+=2;
    fa[2][1]=1;//出口
    for(i=1;i<=9;i++)
    {
        pan[x+ma[i]][y+ma1[i]]=1;
    }
    for(i=2;i<=n;i++)
    {
        for(j=2;j<=m;j++)
        {
            if(pan[i][j]) continue;//找到是1就过
            fa[i][j]=fa[i-1][j]+fa[i][j-1];
            //printf("%lld %d %d\n",fa[i][j],i,j);
        }
    }
    printf("%lld",fa[n][m]);
}

# [USACO1.5][IOI1994]数字三角形 Number Triangles

## 题目描述

观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

```cpp

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

```

在上面的样例中,从 $7 \to 3 \to 8 \to 7 \to 5$ 的路径产生了最大

## 输入格式

第一个行一个正整数 $r$ ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

## 输出格式

单独的一行,包含那个可能得到的最大的和。

## 样例 #1

### 样例输入 #1

```

5

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

```

### 样例输出 #1

```

30

```

## 提示

【数据范围】

对于 $100\%$ 的数据,$1\le r \le 1000$,所有输入在 $[0,100]$ 范围内。

题目翻译来自NOCOW。

USACO Training Section 1.5

IOI1994 Day1T1

这道题目我们要是从最上面那个数来求的话,那时间太久了,我们可以从下面求上去,就欧克啦,思路我就不写了,看代码吧

#include <stdio.h>
int max(int x,int y)
{
    if(x>y) return x;
    else return y;
}
int main()
{
    int i,j,teap;
    int n;
    int a[1001][1001];
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=i;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    for(i=n-1;i>=1;i--)
    {
        for(j=1;j<=i;j++)
        {
            teap=max(a[i+1][j],a[i+1][j+1]);
            a[i][j]=a[i][j]+teap;
        }
    }
    printf("%d",a[1][1]);
}

okok下班下班

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值