问题描述
话说在军训的倒数第二天,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 }