音无结弦之时,天使跃动之心。立于浮华之世,奏响天籁之音。.|

次林梦叶

园龄:3年3个月粉丝:21关注:2

dp---数字三角形模型1--方格取数

 

 

 

 

 

 代码:

复制代码
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 12;
 6 int g[N][N], dp[2*N][N][N], n;//注意这个dp[2*N],一定要写2*N
 7 int main()
 8 {
 9     scanf("%d", &n);
10     int y, x, num;
11     while (cin >> y >> x >> num && (y != 0 || x != 0 || num != 0))
12         g[y][x] = num;
13 
14     for (int k = 1; k <= 2 * n - 1; k++)
15     {
16         for (int i = 1; i <= n; i++)
17         {
18             for (int j = 1; j <= n; j++)
19             {
20                 if (i == j)
21                 {
22                     dp[k][i][j] = max(dp[k - 1][i - 1][j - 1], dp[k][i][j]);
23                     dp[k][i][j] = max(dp[k - 1][i - 1][j], dp[k][i][j]);
24                     dp[k][i][j] = max(dp[k - 1][i][j - 1], dp[k][i][j]);
25                     dp[k][i][j] = max(dp[k - 1][i][j], dp[k][i][j]);
26                     dp[k][i][j] += g[k - i + 1][i];
27                 }
28                 else
29                 {
30                     dp[k][i][j] = max(dp[k - 1][i - 1][j - 1], dp[k][i][j]);
31                     dp[k][i][j] = max(dp[k - 1][i - 1][j], dp[k][i][j]);
32                     dp[k][i][j] = max(dp[k - 1][i][j - 1], dp[k][i][j]);
33                     dp[k][i][j] = max(dp[k - 1][i][j], dp[k][i][j]);
34                     dp[k][i][j] += g[k - i + 1][i]+g[k-j+1][j];
35                 }
36             }
37         }
38     }
39     printf ("%d",dp[2*n-1][n][n]);
40     return 0;
41 }
复制代码

 《其变式----传纸条》

复制代码
 1 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。
 2 
 3 一次素质拓展活动中,班上同学安排坐成一个 m 行 n 列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。
 4 
 5 幸运的是,他们可以通过传纸条来进行交流。
 6 
 7 纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标 (1,1),小轩坐在矩阵的右下角,坐标 (m,n)。
 8 
 9 从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。 
10 
11 在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。
12 
13 班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙,反之亦然。 
14 
15 还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用 0 表示),可以用一个 0100 的自然数来表示,数越大表示越好心。
16 
17 小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度之和最大。
18 
19 现在,请你帮助小渊和小轩找到这样的两条路径。
20 
21 输入格式
22 第一行有 2 个用空格隔开的整数 m 和 n,表示学生矩阵有 m 行 n 列。
23 
24 接下来的 m 行是一个 m×n 的矩阵,矩阵中第 i 行 j 列的整数表示坐在第 i 行 j 列的学生的好心程度,每行的 n 个整数之间用空格隔开。
25 
26 输出格式
27 输出一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。
28 
29 数据范围
30 1≤n,m≤50
31 输入样例:
32 3 3
33 0 3 9
34 2 8 5
35 5 7 0
36 输出样例:
37 34
复制代码

这道题目与上面的题目的唯一区别是:

1.这个题目是从左上角和右下角开始传

2.一定不能通过同一个格子

解决方法:

1.其实从右下角开始传与从左上角开始传没什么区别,可以转化为从左上角开始传

2.通过了同一个格子,其实就已经不是最优解了,可以通过dp淘汰掉,

即我们写代码时可以不那么严谨的写一定不让他们经过同一个格子,最终会发现其实与上面的代码很像

复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 52;
int m, n, g[N][N], t;
int dp[2 * N][N][N];
int main()
{
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
            scanf("%d", &g[i][j]);
    }
    for (int k = 1; k <= m + n - 1; k++)
    {
        for (int i = 1; i <= n && i <= k; i++)
        {
            for (int j = 1; j <= n && j <= k; j++)
            {
                t = g[k - i + 1][i];
                if (i != j)
                    t += g[k - j + 1][j];
                dp[k][i][j] = max(dp[k][i][j], dp[k - 1][i][j]);
                dp[k][i][j] = max(dp[k][i][j], dp[k - 1][i][j - 1]);
                dp[k][i][j] = max(dp[k][i][j], dp[k - 1][i - 1][j]);
                dp[k][i][j] = max(dp[k][i][j], dp[k - 1][i - 1][j - 1]);
                dp[k][i][j] += t;
            }
        }
    }
    printf("%d", dp[m + n - 1][n][n]);
    return 0;
}
复制代码

 

本文作者:次林梦叶

本文链接:https://www.cnblogs.com/cilinmengye/p/16401993.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   次林梦叶  阅读(49)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起