zoukankan      html  css  js  c++  java
  • CH5103 [NOIP2008]传纸条[线性DP]

    给定一个 N*M 的矩阵A,每个格子中有一个整数。现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走。路径经过的格子中的数会被取走。两条路径不能经过同一个格子。求取得的数之和最大是多少。N,M≤50。


    由于走两条路径,可以直接把两个人未知设计入状态中。$f[x1][y1][x2][y2]$表示两个人分别所在处时最大价值。枚举两个人位置(或者,枚举第一个人所在位置,和第二个人所在行,其列也就由路径步数相等推出来了),每种状态分别由之前2*2四个方向转移即可。

    我code可能有bug。。因为这题觉得简单没花太多时间考虑细节。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<queue>
     7 #define dbg(x) cerr<<#x<<" = "<<x<<endl
     8 #define ddbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
     9 using namespace std;
    10 typedef long long ll;
    11 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
    12 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline T read(T&x){
    16     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    17     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    18 }
    19 const int N=50+2;
    20 int f[N][N][N][N],dis[N][N],a[N][N],n,m,y; 
    21 
    22 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
    23     read(n),read(m);
    24     for(register int i=1;i<=n;++i)for(register int j=1;j<=m;++j)read(a[i][j]),dis[i][j]=i+j-2;
    25     f[1][1][1][1]=a[1][1];
    26     for(register int i=1;i<=n;++i){
    27         for(register int j=1;j<=m;++j){
    28             for(register int x=i+1;x<=n;++x){
    29                 y=dis[i][j]-x+2;
    30                 if(y<=0)break;
    31                 MAX(f[i][j][x][y],f[i-1][j][x-1][y]);
    32                 MAX(f[i][j][x][y],f[i-1][j][x][y-1]);
    33                 MAX(f[i][j][x][y],f[i][j-1][x-1][y]);
    34                 MAX(f[i][j][x][y],f[i][j-1][x][y-1]);
    35                 f[i][j][x][y]+=a[i][j]+a[x][y];
    36             }
    37         }
    38     }
    39     printf("%d
    ",f[n-1][m][n][m-1]);
    40     return 0;
    41 }
  • 相关阅读:
    CppUnit
    vconfig in linux
    POSIX semaphore: sem_open, sem_close, sem_post, sem_wait
    (Windows Command) diskpart
    亮块检测及取出亮块的中心坐标
    CacheMetaData Method of Activity
    (C#) Encoding.
    (C#) 线程操作 限制可同时访问某一资源或资源池的线程数。Semaphore 类。Mutex类
    (C# 基础) 跳转 (break, continue, goto, return, throw ).
    (C#基础) 字符串数据和操作
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10692155.html
Copyright © 2011-2022 走看看