zoukankan      html  css  js  c++  java
  • 【NOIP2008提高组T3】传纸条-双线程动态规划

    (本人本题完成于2016-7-18)

    题目大意:一个m*n的矩阵,要从(1,1)开始寻找两条不同路径到(m,n),使经过的点权之和最大,输出这个最大值。

    分析:双线程dp,f[i][j]表示当一条路线(以下称为A路线)走到第i行,另一条路线(以下称为B路线)走到第j行时,已得到的点权之和最大值,不难得出f[i][j]可由四种情况推出:f[i][j](前一步A路线走到i行,B路线走到j行),f[i-1][j](前一步A路线走到i-1行,B路线走到j行),f[i][j-1](前一步A路线走到i行,B路线走到j-1行),f[i-1][j-1](前一步A路线走到i-1行,B路线走到j-1行),设当前所走步数为k,可以得出A路线走到(i,k+2-i),B路线走到(j,k+2-j),则状态转移方程为:

    f[i][j]=max(f[i][j],f[i-1][j],f[i][j-1],f[i-1][j-1])+(i,k+2-i)点权+(j,k+2-j)点权


    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    long m,n,f[51][51]={0},v[51][51]={0}; //m为行数,n为列数,v[i][j]为(i,j)的点权
    
    int main()
    {
      scanf("%ld %ld",&m,&n);
      for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
    	  scanf("%ld",&v[i][j]);
      
      for(int k=0;k<=n+m-2;k++) //k枚举步数
        for(int i=m;i>=1;i--)
    	  for(int j=m;j>=1;j--) //注意i,j两重循环顺序,保证结果正确性
    	  {
    	    if (k==n+m-2&&i==m&&j==m) //最后的结果特殊判断
    		  f[i][j]=max(max(f[i][j],f[i-1][j-1]),max(f[i-1][j],f[i][j-1]))+v[i][k+2-i]+v[j][k+2-j];
    	    else if (i!=j&&k+2-i>=1&&k+2-j>=1) //条件i!=j是为防止两路线走到同一个点,其余两个条件是为防止坐标超越边界
    		  f[i][j]=max(max(f[i][j],f[i-1][j-1]),max(f[i-1][j],f[i][j-1]))+v[i][k+2-i]+v[j][k+2-j];
    	  }
      
      printf("%ld",f[m][m]);
      return 0;
    }

  • 相关阅读:
    畅销书排行榜
    阿里云大数据产品体系
    天然气收费管理系统的研究与实现随笔
    Web端实现RTC视频特效的解决方案
    从0搭建在线聊天室,只需4步!
    技术干货 | JavaScript 之事件循环(Event Loop)
    C++20 四大特性之一:Module 特性详解
    Android Flutter 多实例实践
    网易云信线上万人连麦技术大揭秘
    Python + Pytest 自动化框架的用例依赖实操
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9794030.html
Copyright © 2011-2022 走看看