zoukankan      html  css  js  c++  java
  • 洛谷P7074 [CSP-J2020] 方格取数——题解

    [CSP-J2020] 方格取数

    一道dp题。难度不大,但是个典型的dp考法,值得一说。

    看一眼题,容易写出dp方程ans[i][j]=max{ans[i-1][j],ans[i][j-1],ans[i+1][j]}+val[i][j]。但发现难以确定dp递推的顺序。但思考一会后,又发现dp方程可拆分成两种情况,因为不能走重复的格子,所以对于当前的格子(i,j),要么从上方、左边走过来,且同一列的路径格子的进入方式也为上方/左边;要么从下方、左边走过来,且同一列的路径格子的进入方式也为下方/左边。即dp状态转移可拆分成两种情况,且在其中一种情况中,转移方程都一样。拆分后容易找到明显的转移顺序,最后再合并一下就好。

     1 #include<iostream>
     2 #include<cstdio>
     3 
     4 using namespace std;
     5 
     6 const int N=1e3+5;
     7 const long long FINF=-20000000000ll;
     8 
     9 int n,m;
    10 
    11 long long up[N][N],down[N][N],ans[N][N],mp[N][N];
    12 
    13 inline int read()//Z 
    14 {
    15     int x=0;
    16     char ch=getchar();
    17     bool f=0;
    18     while(!isdigit(ch))
    19         f|=ch=='-',ch=getchar();
    20     while(isdigit(ch))
    21         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    22     return f?-x:x;
    23 }
    24 
    25 int main()
    26 {
    27     n=read(),m=read();
    28     for(int i=1;i<=n;++i)
    29         for(int j=1;j<=m;++j)
    30             mp[i][j]=read();
    31     for(int i=1;i<=n;++i)
    32         ans[i][1]=ans[i-1][1]+mp[i][1];
    33     for(int j=2;j<=m;++j)
    34     {
    35         up[0][j]=down[n+1][j]=FINF;
    36         for(int i=1;i<=n;++i)
    37             up[i][j]=max(up[i-1][j],ans[i][j-1])+mp[i][j];
    38         for(int i=n;i>=1;--i)
    39             down[i][j]=max(down[i+1][j],ans[i][j-1])+mp[i][j];
    40         for(int i=1;i<=n;++i)
    41             ans[i][j]=max(up[i][j],down[i][j]);
    42     }
    43     printf("%lld",ans[n][m]);
    44     return 0;
    45 } 
    AC代码
  • 相关阅读:
    boost之实用工具
    boost之内存池
    boost之智能指针
    boost之日期date_time
    boost之时间timer
    boost之网络通信
    boost之定时器和io_service
    【Linux 线程】线程同步《一》
    【Linux 线程】常用线程函数复习《四》
    【Linux 线程】常用线程函数复习《三》
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/14323910.html
Copyright © 2011-2022 走看看