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 表示),可以用一个 0∼100 的自然数来表示,数越大表示越好心。 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 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步