zoukankan      html  css  js  c++  java
  • Luogu P1004/P1006 方格取数/传纸条 【棋盘Dp】 By cellur925

    我明明记得写过这篇啊qwq为什么会搞丢

    两题几乎一样。

    如果再拓展到k条路,就要用网络流跑了,本蒟现在还不会。

    我们容易想到四维dp,但是有一种更好的方法。

    首先,先从左上到右下、再从右下到左上可以近似地等效为求从给定的起点出发走到指定位置的两条最短严格不相交路线。即两条路线同时搞。

    其次,我们会记录到两个点的坐标,横纵坐标都要记录,太麻烦。要是知道当前在第几步,只枚举横坐标或是纵坐标就能求解。我们就用到这个方法。显然从左上到右下需要走n+m-2步,起点不算。然而dalao们却都习惯把起点当作第一步,走完便变成了n+m-1步,方便起见,我们使用这种表示。枚举当前在第几步(第几个格子),分别枚举两个路线的横坐标,便可知纵坐标。这是转移。

    由于路线不能有冲突,所以我们特判一下如果走到了一个地方就减去一个格子的权值。

    由于属于棋盘类,所以还有细节注意是否越界。

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 int n,m;
     7 int w[100][100]; 
     8 int f[120][60][60];
     9 
    10 int main()
    11 {
    12     scanf("%d%d",&n,&m);
    13     for(int i=1;i<=n;i++)
    14      for(int j=1;j<=m;j++)
    15       scanf("%d",&w[i][j]);
    16     //n+m-1 ??? 
    17     for(int k=1;k<=n+m-1;k++)
    18      for(int i=1;i<=n;i++)
    19       for(int j=1;j<=n;j++)
    20       {
    21            if(k-i+1<1||k-j+1<1) continue;
    22            f[k][i][j]=max(max(f[k-1][i-1][j-1],f[k-1][i][j-1]),max(f[k-1][i-1][j],f[k-1][i][j]))+w[i][k-i+1]+w[j][k-j+1];
    23          if(i==j) f[k][i][j]-=w[i][k-i+1]; 
    24       }
    25     printf("%d",f[n+m-1][n][n]);
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    二维数组求矩形最大子数组和
    关于返回一个整数数组中最大子数组的和的问题(详细版)
    学习进度第三周
    人月神话阅读笔记03
    团队开发项目-NABCD模型
    第七周学习总结
    人月神话阅读笔记01
    第六周学习总结
    大道至简阅读笔记03
    结对开发地铁查询
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9475438.html
Copyright © 2011-2022 走看看