题目链接:P1006 传纸条

 

PS:伤心,又想不出来,看了大神的题解

 

AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,f[210][210],a[210][210];
int main()
{
    ll i,j,k;
    cin>>n>>m;
    for (i=1;i<=n;++i)
        for (j=1;j<=m;++j)
            cin>>a[i][j];

    f[1][2]=a[1][2]+a[2][1];//不管怎样都会经过(1,2)和(2,1)先赋初值
    //i是当前的点横纵坐标之和
    //下面的循环是起码2*3或者3*2棋盘才会进入,如果2*2及以下棋盘已经初定义了
    for (i=4;i<n+m;++i)//至于i<n+m我是画草图才理解的
    {
        for (j=min(i-2,n);j>=1;j--) //滚动数组,i层和i-层有关,所以j,k要一直减小而不是增大,防止数据覆盖
        {//j=min(i-2,n)是在不超出的情况下找尽量小的能走的位置
            for (k=min(i-1,n);k>j;k--)
            {//k在j右边,所以是i-1
                if (j>1)  //这里的条件判断貌似是不需要的,但加上更好
                {
                    f[j][k]=max(f[j][k],f[j-1][k]);
                }
                if (j>1&&k>1)
                {
                    f[j][k]=max(f[j][k],f[j-1][k-1]);
                }
                if (k-1>j)//保证移动前的点没有重合
                {
                    f[j][k]=max(f[j][k],f[j][k-1]);
                }
                //对于两个都从上边来的,其实是另一对(j,k)的两个都从左边来,所以不用写了
                f[j][k]+=a[j][i-j]+a[k][i-k];//把数字带上
            }
        }
    }

    cout<<f[n-1][n];//输出左下角左边和上边两个格的数字和就好了

    return 0;
}
点击加号展开代码

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-08-22
  • 2022-01-05
  • 2022-12-23
  • 2022-12-23
  • 2021-05-31
猜你喜欢
  • 2021-11-17
  • 2022-01-10
  • 2021-07-29
  • 2022-12-23
  • 2022-03-04
  • 2021-10-19
  • 2022-12-23
相关资源
相似解决方案