双线程DP (三维法四维法) sdnu 1032.机器人 1194.传纸条

来源:互联网 发布:mysql 修改列字符集 编辑:程序博客网 时间:2024/06/01 07:14

原题链接:

1032:   http://210.44.14.31/problem/show/1032

1194:   http://210.44.14.31/problem/show/1194


状态转移方程:

三维:

dp[k][i][j] = max(dp[k - 1][i][j], dp[k - 1][i - 1][j], dp[k - 1][i][j - 1], dp[k-1][i - 1][j - 1])+jz[i][k+2-i]+jz[j][k+2-j];

四维:

dp[i1][j1][i2][j2] = max(dp[i1 - 1][j1][i2 - 1][j2], dp[i1 - 1][j1][i2][j2 - 1], dp[i1][j1 - 1][i2 - 1][j2], dp[i1][j1 - 1][i2][j2 - 1]) + jz[i1][j1] + jz[i2][j2];


分析见代码。

四维:

#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std;int dp[51][51][51][51];int jz[52][52];int max(int a, int b, int c, int d)//求四个数中的最大数。(三维法代码上的更快){int x = a > b ? a : b;int y = c > d ? c : d;return x > y ? x : y;}int main(){int n, m;scanf("%d%d", &n, &m);for (int i = 1; i <= n;i++)for (int j = 1; j <= m; j++)scanf("%d",&jz[i][j]);for (int i1 = 1; i1 <= n;i1++)//i1,j1代表第一个,i2,j2代表第二个。for (int j1 = 1; j1 <= m;j1++)for (int i2 = 1; i2 <= n;i2++)for (int j2 = 1; j2 <= m; j2++){dp[i1][j1][i2][j2] = max(dp[i1 - 1][j1][i2 - 1][j2], dp[i1 - 1][j1][i2][j2 - 1], dp[i1][j1 - 1][i2 - 1][j2], dp[i1][j1 - 1][i2][j2 - 1]) + jz[i1][j1] + jz[i2][j2];if (i1 == i2&&j1 == j2)//重叠时减去一个dp[i1][j1][i2][j2] -= jz[i1][j1];}cout << dp[n][m][n][m];//无换行return 0;}

三维:

#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std;int dp[105][51][51];int jz[52][52];int max(int a, int b, int c, int d)//求四个数中的最大数{if (a >= b&&a >= c&&a >= d) return a;else if (b >= c&&b >= d) return b;else if (c >= d) return c;else return d;}int main(){int n, m;scanf_s("%d%d", &n, &m);//注意:虽然输入是 n,m  但矩阵是 m*n。。呵呵~for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf_s("%d", &jz[i][j]);int sumbs = m + n - 2;//算出一共需要走多少步。(自己可以在演草纸上画一下,易得出)for (int k = 1; k <= sumbs; k++)//  注意:k=i+向下走的步数-2所以下文   k+2-i  k+2-j 分别表示第一个向下走的步数和第二个向下走的步数for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++){if (i != j&&k + 2 - i >= 1 && k + 2 - j >= 1)//1.保证不重叠  2.保证在范围内(k + 2 - i >= 1 && k + 2 - j >= 1也可不写,不写耗时间你懂~)  dp[k][i][j] = max(dp[k - 1][i][j], dp[k - 1][i - 1][j], dp[k - 1][i][j - 1], dp[k - 1][i - 1][j - 1]) + jz[i][k + 2 - i] + jz[j][k + 2 - j];}cout << dp[sumbs][n][n - 1];//易理解:dp[sumbs][n][n - 1]==dp[sumbs][n - 1][n]; 注意:本程序不包含第一个点(即jz[1][1])return 0;}











0 0
原创粉丝点击