zy 送画

问题描述
话说在军训的倒数第二天,zy终于下定决心要将画了 10天之久的画像送给他心怡的法
学院mm。但是,他不敢自己一个人去,倒霉的 kk 只能和他一起去了。不过,为了表现的有
诚意,kk和zy不能走在一起,要不然被对方看见就不好了。那么到底要怎么走呢?zy给了
kk 一幅地图,他把学校分成了 n*m 个格子,对于每个格子,zy 写下了一个数字表示他对于
这个格子的好感度(好感度当然是 zy 自己定义的) ,入口在左上角(1,1)点,出口在右下
角(n,m),zy 和 kk 需要从左上角一起出发,在右下角会和,因为 zy 非常害羞,所以中间
kk和zy都只向右或向下走,这样走完全程的时间最短, 但中间两人不能走到同一个格子上。
经过深思熟虑,他决定,需要他和 kk 走的路的好感度总和最大才是最好。现在,zy 和 kk
希望你能告诉他们两个人各自要走那一条路。为了简化问题,你只需告诉他们两个好感度总
和就可以了。你可以假设mm一定会在zy的路上。
 
输入描述
第一行两个整数 n,m。
接下来n行每行 m个整数,每两个整数之间用一个空格隔开。
 
输出描述
一行一个整数表示最大好感度和。注意,起点和终点的好感度值只计入一次。

样例输入
3 4
1 2 3 4
5 6 7 8
9 10 11 12
 
样例输出
71
 
数据范围
2<=n,m<=50。
好感度为10000以内的正整数。
 

这道题与08年noip传纸条相当相似,虽然我并没有做过传纸条。

我是用递归做的,枚举两个人在一个时间点到的点,

如果相同就返回。

设置坐标0,0为之前已经到了终点,就只需要搜另一个人的路径了,

当某人到了终点时,下一次坐标就会为0,0,也是只需搜另一个人的路径了。

再加记忆数组,过完。

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdlib>
 4 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
 5 using namespace std;
 6 
 7 ifstream fin("paint.in");
 8 ofstream fout("paint.out");
 9 
10 int cnt_heng=0,cnt_lie=0;
11 int jiyi[52][52][52][52]={0};
12 int jv[52][52];
13 
14 int dp(int he1,int zo1,int he2,int zo2){
15 if(he1==cnt_heng&&zo1==cnt_lie)
16 if(he2==cnt_heng&&zo2==cnt_lie)return jv[cnt_heng][cnt_lie];
17 if(he1==he2&&zo1==zo2)return 0;
18 if(he1>cnt_heng||he2>cnt_heng)return 0;
19 if(zo2>cnt_lie||zo1>cnt_lie)return 0;
20 if(jiyi[he1][zo1][he2][zo2]!=0)return jiyi[he1][zo1][he2][zo2];
21 int a[2]={0,1},b[2]={1,0};
22 int tem=0;
23 if(he1==cnt_heng&&zo1==cnt_lie){    
24  if(he2==0&&zo2==0)return 0;
25  for(int x=0;x<=1;x++)
26    tem=max(tem,dp(0,0,he2+a[x],zo2+b[x]));
27   jiyi[he1][zo1][he2][zo2]=tem+jv[he1][zo1]+jv[he2][zo2];
28   return tem+jv[cnt_heng][cnt_lie]+jv[he2][zo2];    
29 }
30 
31 if(he2==cnt_heng&&zo2==cnt_lie){
32  if(he1==0&&zo1==0)return 0;    
33  for(int x=0;x<=1;x++)
34    tem=max(tem,dp(he1+a[x],zo1+b[x],0,0));
35   jiyi[he1][zo1][he2][zo2]=tem+jv[he1][zo1]+jv[he2][zo2];
36   return tem+jv[cnt_heng][cnt_lie]+jv[he1][zo1];        
37 }
38 if(he1==0&&zo1==0){
39  for(int x=0;x<=1;x++)
40   tem=max(tem,dp(0,0,he2+a[x],zo2+b[x]));    
41   jiyi[he1][zo1][he2][zo2]=tem+jv[he2][zo2];
42   return tem+jv[he2][zo2];
43  }
44 if(he2==0&&zo2==0){
45  for(int x=0;x<=1;x++)
46    tem=max(tem,dp(he1+a[x],zo1+b[x],0,0));
47   jiyi[he1][zo1][he2][zo2]=tem+jv[he1][zo1];
48   return tem+jv[he1][zo1];            
49 }
50 
51 for(int x=0;x<=1;x++)
52  for(int y=0;y<=1;y++){
53   tem=max(tem,dp(he1+a[x],zo1+b[x],he2+a[y],zo2+b[y])); 
54  }
55  jiyi[he1][zo1][he2][zo2]=tem+jv[he1][zo1]+jv[he2][zo2];
56  return tem+jv[he1][zo1]+jv[he2][zo2];
57 }
58 
59 int main(int argc, char** argv) {
60 fin>>cnt_heng>>cnt_lie;
61 for(int x=1;x<=cnt_heng;x++)
62  for(int y=1;y<=cnt_lie;y++)fin>>jv[x][y];      
63  
64 int ans=dp(1,2,2,1);      
65 ans+=jv[1][1];
66 cout<<ans;
67 fout<<ans;
68  
69  return 0;
70 }
原文地址:https://www.cnblogs.com/Ateisti/p/4869975.html