码迷,mamicode.com
首页 > 其他好文 > 详细

P1006 传纸条

时间:2020-04-25 19:34:54      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:clu   tps   sed   mic   nbsp   tar   targe   turn   window   

 

链接

刚开始想的是两次01背包,把第一次走过的给记录下来。好像不太好记录,

参考了大佬的博客,数据范围不是很大,四维数组就可以了,

a,b第一个人走的,c,d代表第二个人

dp[a][b][c][d] = max{dp[a][b -1][c][d -1] , dp[a - 1][b][c -1][d],

                             dp[a][b -1][c -1][d],dp[a - 1][b][c][d -1]}+a[a][b] + a[c][d];

 只要保证纵坐标不一样就行,d = b + 1开始循环

最后输出是dp[n][m - 1][n - 1][m];

第一个人到第二个人只能往右或者往下走,所以到达的点是n,m-1

同理,第二个人到达的点是n-1,m;

 

如果卡的厉害,可以变为三维数组,怎么操作呢?

每次转移的时候,两个人走的步数是相等的,

枚举横坐标

k表示总的步数,

技术图片

 

 

 

技术图片
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 int a[55][55],dp[110][55][55];
 5 int n,m;
 6 
 7 int main(){
 8     //freopen("in","r",stdin);
 9     ios::sync_with_stdio(0);
10     cin >> n >> m;
11     for(int i = 1; i <= n; i++){
12         for(int j = 1; j <= m; j++){
13             cin >> a[i][j];
14         }
15     }
16     for(int k = 1; k <= n + m - 1; k++){
17         for(int i = 1; i <= n; i++){
18             for(int j = 1; j <= n; j++){
19                 if(k - i < 0 || k - j < 0)
20                     continue;
21                 dp[k][i][j] = max(max(dp[k - 1][i][j],dp[k - 1][i - 1][j - 1]),max(dp[k - 1][i][j - 1],dp[k - 1][i - 1][j])) + a[i][k - i + 1] + a[j][k - j + 1];
22                 if(i == j)
23                     dp[k][i][j] -=  a[i][k - i + 1];
24             }
25         }
26     }
27     cout << dp[n + m - 1][n][n] << endl;
28     return 0;
29 }
View Code

 

P1006 传纸条

标签:clu   tps   sed   mic   nbsp   tar   targe   turn   window   

原文地址:https://www.cnblogs.com/xcfxcf/p/12774167.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!