算法入门-[NOIP2008]传纸条

[NOIP2008]传纸条

https://ac.nowcoder.com/acm/problem/16615

#双线dp

  • 双线表示同时有两种状态,且会相互影响

题意

  • 给定M*N的地图,每个点有val,每个点只能走一次
  • 从左上走到右下再走回左上,且向下的过程只能向下向右,向上的过程只能向上向左
  • 走完最多获得的val是多少

思路

  • 思路一:严格按照一圈走无法完成,走下去的过程走过的格子会影响走上去的过程的路径,不妨同时完成,又走上去和走下去完全相同,不妨设两个人同时从起点出发,走到终点,用四维的dp来记录两个人的位置,当两个人重叠的时候就把dp记为无穷小
  • 思路二:可以发现,两个人走的步数是相同的,我们只用记录来表示走了k步,第一个人向下走了i步,第二个人向下走了j步,同样地,当i=j时记为无穷小

代码

#include<bits/stdc++.h>

using namespace std;

/**
 * dp[i][j][k][l]第一个人在(i,j)第二个在(k,l)和最大
 * dp[i][j][k][l]=dp四个方向
 */
int dp[60][60][60][60];
int a[60][60];
int n,m;

int judge(int i,int j,int k,int l){
    if(i==1&&j==1&&k==1&&l==1)return 0;
    if(i==m&&j==n&&k==m&&l==n)return 0;
    return 1;
}
int main(){
    cin >> m >> n;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cin >> a[i][j];
        }
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=m;k++){
                for(int l=1;l<=n;l++){
                    if(i==k&&j==l&&judge(i,j,k,l)) dp[i][j][k][l]=-0x3f3f3f3f;
                    else dp[i][j][k][l]=max(dp[i-1][j][k-1][l],max(dp[i-1][j][k][l-1],max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1])))+a[i][j]+a[k][l];

                }
            }
        }
    }
    cout << dp[m][n][m][n] <<endl;
    return 0;
}
全部评论

相关推荐

05-26 22:25
门头沟学院 Java
Java小肖:不会是想叫你过去把你打一顿吧,哈哈哈
点赞 评论 收藏
分享
程序员小白条:找的太晚,别人都是大三实习,然后大四秋招春招的,你大四下了才去实习,晚1年
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务