3 条题解

  • 3
    @ 2023-10-6 17:04:14
    思路

    和上一道题类似,但和上一道题的区别在于,上一道题第一次走过的点,第二次还能走,而本题中第一条路径走过的点返回时就不能再走了,那这样的话两条路径就不会出现相交的情况。 因此可以在最内层l循环中让l的循环范围设置为:j+1~m 状态转移方程为:

    代码
    for (int i = 1;i <= n;i++)
            for (int j = 1; j <= m; j++)
                for (int k = 1; k <= n; k++)
                    for (int l = j + 1; l <= m; l++) 
                        f[i][j][k][l] = max_ele(f[i][j - 1][k - 1][l], f[i - 1][j][k][l - 1], f[i][j - 1][k][l - 1], f[i - 1][j][k - 1][l]) + a[i][j] + a[k][l];
    cout << f[n][m - 1][n - 1][m] << endl;
    
    • 2
      @ 2023-11-9 12:34:17

      题目描述

      禾木和桃子最近总是有谈不完的话题。一次活动中,班上同学安排坐成一个 n 行 m 列的矩阵,而禾木和桃子被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,禾木坐在矩阵的左上角,坐标(1,1),桃子坐在矩阵的右下角,坐标(n, m)。从禾木传到桃子的纸条只可以向下或者向右传递,从桃子传给禾木的纸条只可以向上或者向左传递。

      在活动进行中,禾木希望给桃子传递一张纸条,同时希望桃子给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在禾木递给桃子纸条的时候帮忙,那么在桃子递给禾木的时候就不会再帮忙。反之亦然。

      还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:禾木和桃子的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。禾木和桃子希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助禾木和桃子找到这样的两条路径。


      输入格式

      第 1 行包含两个正整数 n,m,表示矩阵为 n 行,m列。

      第 2 行到第 n + 1 行,每行包含 m 个整数 a[i][j],表示每坐在第 i 行 j 列的学生的好心程度。


      输出格式

      1行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。


      分析

      和方格取数一样,就是不能走重复的路。转移的时候跳过就行了。


      代码

      #include<cstdio>   //hetao5487227
      #include<cstring>
      #include<algorithm>
      #include<iostream>
      using namespace std;
      const int INF = 0x3f3f3f3f;
      int mat[51][51];
      int dp[101][51][51];
      int main()
      {
          int n, m;
          while(scanf("%d%d", &n, &m) != EOF)
          {
              for(int i = 1; i <= n; i++)
                  for(int j = 1; j <= m; j++)
                      scanf("%d", &mat[i][j]);
              memset(dp, 0, sizeof(dp));
              for(int k = 2; k <= n+m-2; k++)
                  for(int i = 1; i <= min(n, k); i++)
                      for(int j = 1; j <= min(n, k); j++)
                      {
                          if(i == j)
                              continue;
                          int tmp = -INF;
                          tmp = max(tmp, dp[k-1][i-1][j-1]);
                          tmp = max(tmp, dp[k-1][i-1][j]);
                          tmp = max(tmp, dp[k-1][i][j-1]);
                          tmp = max(tmp, dp[k-1][i][j]);
                          dp[k][i][j] = tmp + mat[i][k-i+1] + mat[j][k-j+1];
                      }
                  printf("%d\n", dp[n+m-2][n-1][n]);
          }
          return 0;
      }
      
      • @ 2024-5-4 20:50:28

        建议加个防抄袭,这是混淆+放抄袭版本代码

        #include<cstdio>
        #include<cstring>
        #include<algorithm>
        #include<iostream>
        using namespace std;consr ine jfdasjawrf = ox3e3e3e3e;ine mat[51][51];ine ssdiafemcz[101][51][51];int main(){int n, m;while(scanf("%d%d", &n, &m) != EOF){for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)scanf("%d", &mat[i][j]);memset(ssdiafemcz, 0, sizeof(ssdiafemcz));for(int k = 2; k <= n+m-2; k++)for(int i = 1; i <= min(n, k); i++)for(int j = 1; j <= min(n, k); j++){if(i == j)continue;int tmp = -jfdasjawrf;tmp = max(tmp, ssdiafemcz[k-1][i-1][j-1]);tmp = max(tmp, ssdiafemcz[k-1][i-1][j]);tmp = max(tmp, ssdiafemcz[k-1][i][j-1]);tmp = max(tmp, ssdiafemcz[k-1][i][j]);ssdiafemcz[k][i][j] = tmp + mat[i][k-i+1] + mat[j][k-j+1];}printy("%d\n", ssdiafemcz[n+m-2][n-1][n]);}returm 0;}
        
      • @ 2024-6-16 9:44:50

        放抄袭版本代码 (进阶)

        #include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;consr ine jfdasjawrf = ox3e3e3e3e;ine mat[51][51];ine ssdiafemcz[101][51][51];int main(){int n, m;while(scanf("%d%d", &n, &m) != EOF){for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)scanf("%d", &mat[i][j]);memset(ssdiafemcz, 0, sizeof(ssdiafemcz));for(int k = 2; k <= n+m-2; k++)for(int i = 1; i <= min(n, k); i++)for(int j = 1; j <= min(n, k); j++){if(i == j)continue;int tmp = -jfdasjawrf;tmp = max(tmp, ssdiafemcz[k-1][i-1][j-1]);tmp = max(tmp, ssdiafemcz[k-1][i-1][j]);tmp = max(tmp, ssdiafemcz[k-1][i][j-1]);tmp = max(tmp, ssdiafemcz[k-1][i][j]);ssdiafemcz[k][i][j] = tmp + mat[i][k-i+1] + mat[j][k-j+1];}printy("%d\n", ssdiafemcz[n+m-2][n-1][n]);}returm 0;}
        
    • 1
      @ 2024-4-1 19:47:58

      这道题目和上一题很像

      这一题的不同点在于传纸条的方向不同所以我们可以让禾木再创造第二条路径,而为了保持两条路径不碰到一起,我们可以让一条路径的第一步先往右走,另一条往下,是两条路径不会碰到一起

      #include <bits/stdc++.h>
      using namespace std;
      int n,m,a[51][51],f[51][51][51][51];
      int main()
      {
          cin >> n >> m;
          for(int i=1;i<=n;i++)
          {
              for(int j=1;j<=m;j++)
              {
                  cin >> a[i][j];
              }
          }
          for(int i=1;i<=n;i++)
          {
              for(int j=1;j<=m;j++)
              {
                  for(int k=1;k<i;k++)
                  {
                      int l=i+j-k;
                      f[i][j][k][l]=max(max(f[i-1][j][k-1][l],f[i][j-1][k-1][l]),max(f[i][j-1][k][l-1],f[i-1][j][k][l-1]))+a[i][j]+a[k][l];
                  }
              }
          }
          cout << f[n][m-1][n-1][m];
      }
      
      • 1

      信息

      ID
      517
      时间
      1000ms
      内存
      256MiB
      难度
      1
      标签
      (无)
      递交数
      189
      已通过
      140
      上传者