算法提高之方格取数

算法提高之方格取数

  • 核心思想:数字三角形模型

    • 考虑同时走两条路 用f[i1][j1][i2][j2]表示两条路取值

    • 因为两条路步数一定相同 即i1+j1 == i2+j2 设为k

      • 则f[k][i1][i2]即可表示两条路 k = n*2
    • 在这里插入图片描述

      • dp方法如图
  •   #include <iostream>
      #include <cstring>
      #include <algorithm>
      
      using namespace std;
      const int N = 11;
      int g[N][N],f[2*N][N][N];
      int n;
      
      int main()
      {
          cin>>n;
          int a,b,c;
          while(cin>>a>>b>>c , a||b||c) g[a][b] = c;
          
          for(int k=2;k<=2*n;k++)  //步数增加
              for(int i1=1;i1<=n;i1++)
                  for(int i2=1;i2<=n;i2++)
                  {
                      int j1=k-i1,j2=k-i2;  //取坐标
                      if(j1<1 || j2<1 || j1>n || j2>n) continue;  //出界
                      int &x = f[k][i1][i2];  //当前格子的f
                      int t = g[i1][j1];  //t为这一步要加的数
                      if(i1!=i2) t+=g[i2][j2];  //如果两条路在该点不重合 则两个格子的数都取
                      //dp
                      x = max(x,f[k-1][i1-1][i2-1]+t);
                      x = max(x,f[k-1][i1-1][i2]+t);
                      x = max(x,f[k-1][i1][i2-1]+t);
                      x = max(x,f[k-1][i1][i2]+t);
                  }
          cout<<f[2*n][n][n]<<endl;
      }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值