【NOIP2008】传纸条

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1006#sub


这道题和那道方格取数很像,都是多线程DP,模拟两条路走。具体实现看代码,但这种多线程的题有几个点需要注意:

1、dp数组的维度要够,因为是模拟多条路线。

2、多条路线交叉,交叉点只取一次。

3、路线必须起点相同,终点相同,不能正反颠倒,因为每个点只会取一次,假如起点终点不同,结果必受影响。

4、过程中路线会交叉,但最终答案路线是不会交叉的,因为如果两条路线交叉,必然存在两条不交叉且答案更大的路线。

 1 #include<cstdio>
 2 inline int max(int a,int b) {return a>b?a:b;}
 3 const int mmax=55;
 4 int n,m,map[mmax][mmax],dp[mmax][mmax][mmax][mmax];
 5 int main() {
 6     scanf("%d%d",&n,&m);
 7     for(int i=1;i<=n;++i)
 8         for(int j=1;j<=m;++j) scanf("%d",&map[i][j]);
 9     for(int i=1;i<=n;++i)
10         for(int j=1;j<=m;++j)
11             for(int k=1;k<=n;++k)
12                 for(int l=1;l<=m;++l) {
13                     dp[i][j][k][l]=max(dp[i-1][j][k-1][l],max(dp[i-1][j][k][l-1],max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1])))+map[i][j];
14                     if(!(i==k&&j==l)) dp[i][j][k][l]+=map[k][l];
15                 }
16     printf("%d",dp[n][m][n][m]);
17     return 0;
18 }
AC代码

猜你喜欢

转载自www.cnblogs.com/Mr94Kevin/p/9613307.html