SWUST OJ 1084 Mzx0821月赛系列之情书

    xiaoxiao2025-09-06  663

    题目:http://acm.swust.edu.cn/problem/1084/

    思路:最开始想的是使用dfs,但不知道怎么保证求出一次最短路径的最大保密性之后,求另外一条不相交的路径,后来看了学长的博客之后,每次就两条路径都同步走,只要不是同一个点就不会相交,而且学长用的是双线程dp,我就按照学长的思路,写了这道题。

    首先用一个dp[i][j][x][y];来存两条路径的最大保密性的和,

    每的点对应的路径就是两个路径的左边和上边的最大值加上当前点的保密性。因为是最短路径,就只能是上边和左边

    dp[i][j][x][y]=max(dp[i-1][j][x-1][y],max(dp[i-1][j][x][y-1],max(dp[i][j-1][x-1][y],dp[i][j-1][x][y-1])))+mpt[x][y]+mpt[i][j]; #include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <math.h> #include <queue> #include <vector> #include <map> using namespace std; typedef long long LL; typedef unsigned long long UL; #define MS(x,y) memset(x,y,sizeof(x)) #define rpt(i,l,r) for(int i=l;i<=r;i++) #define rpd(i,r,l) for(int i=r;i>=l;i--) LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b);} #define N 1000005 int n,m; int mpt[55][55]; int dp[55][55][55][55]; int main(){ while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&mpt[i][j]); } } memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){//最好是从1开始,因为后面的x-1,y-1,i-1,j-1存在越界的情况,从1开始就不用考虑了,越界了得值就已经初始化为0了 for(int j=1;j<=m;j++){ for(int x=i+1;x<=n;x++)//x=i+1保证始终x,y的那条路径在i,j路径的下面。 { int y=i+j-x;//因为i+j=x+y; 说明二者的时间是同步的 if(y<=0) continue; dp[i][j][x][y]=max(dp[i-1][j][x-1][y],max(dp[i-1][j][x][y-1],max(dp[i][j-1][x-1][y],dp[i][j-1][x][y-1])))+mpt[x][y]+mpt[i][j]; } } } printf("%d\r\n",dp[n-1][m][n][m-1]); } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1302384.html
    最新回复(0)