标题叙述 Description,小渊和小轩希望尽或许找好心程度高的同校来襄助传纸条

1169 传纸条

二零零六年NOIP全国联赛升高组

时间限制: 1 s

空间范围: 12七千 KB

标题等级 : 钻石 Diamond

 

 

 

 

难题叙述 Description

小渊和小轩是好情人也是同班同学,他们在联名总有谈不完的话题。五次素质进行移动中,班上同学布署做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的双方,由此,他们就不大概直接交谈了。幸运的是,他们可以透过传纸条来举办互换。纸条要路过许多同班传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只好向下依然向右传递,从小轩传给小渊的纸条只能提升或许向左传递。

在活动展开中,小渊希望给小轩传递一张纸条,同时希望小轩给她回复。班里各种同学都得以帮她们传递,但只会帮他们一遍,相当于说若是此人在小渊递给小轩纸条的时候援救,那么在小轩递给小渊的时候就不会再支持。反之亦然。

再有一件业务须要小心,全班每种同学愿意帮助的钟情度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),能够用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽只怕找好心程度高的同室来救助传纸条,即找到来回两条传递路径,使得那两条路径上同校的好心程度只和最大。未来,请您帮助小渊和小轩找到这么的两条途径。

输入描述 Input Description

输入的第贰行有三个用空格隔开的平头m和n,表示班里有m行n列(1<=m,n<=50)。

接下去的m行是三个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学童的美意程度。每行的n个整数之间用空格隔开。

出口描述 Output Description

输出共一行,包蕴一个整数,表示过往两条路上插足传递纸条的学童的好心程度之和的最大值。

样例输入 Sample Input

3 3

0 3 9

2 8 5

5 7 0

样例输出 萨姆ple Output

34

数量范围及提醒 Data Size & Hint

3/10的数据满意:1<=m,n<=10

百分百的数目满意:1<=m,n<=50

难点叙述 Description

分拣标签 Tags 点此进行

 

好吧那种样式的动规确实有点刁钻

我们得以用贰个四维数组来记录两条路线

动态转换方程

图片 1

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXN=51;
 6 const int maxn=1001;
 7 int map[MAXN][MAXN];
 8 int f[MAXN][MAXN][MAXN][MAXN];
 9 int main()
10 {
11     int n,m;
12     scanf("%d%d",&n,&m);
13     for(int i=1;i<=n;i++)
14     {
15         for(int j=1;j<=m;j++)
16         {
17             scanf("%d",&map[i][j]);
18         }
19     }
20     for(int i=1;i<=n;i++)
21     {
22         for(int j=1;j<=m;j++)
23         {
24             for(int k=1;k<=n;k++)
25             {
26                 for(int l=j+1;l<=m;l++)// 注意l必须等于j+1才能保证两条路线不相交 
27                 {
28                     f[i][j][k][l]=map[i][j]+map[k][l]+max(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]));
29                 }                        // 1上   2上         1 up    2left        1left 2up                   
30             }
31         }
32     }
33     printf("%d",f[n][m-1][n-1][m]);
34     return 0;
35 }

 

小渊和小轩是好对象也是同班同学,他们在一道总有谈不完的话题。两回素质拓展活动中,班上同学布署做成多少个m行n列的矩阵,而小渊和小轩被布署在矩阵对角线的相互,因而,他们就不只怕直接交谈了。幸运的是,他们得以因此传纸条来开展交换。纸条要路过许多同校传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只好向下或许向右传递,从小轩传给小渊的纸条只能提升恐怕向左传递。

在运动举行中,小渊希望给小轩传递一张纸条,同时愿意小轩给她恢复生机。班里每一种同学都可以帮她们传递,但只会帮她们四遍,约等于说若是此人在小渊递给小轩纸条的时候协理,那么在小轩递给小渊的时候就不会再匡助。反之亦然。

再有一件事情须要小心,全班每一个同学愿意帮助的酷爱度有高有低(注意:小渊和小轩的好意程度没有定义,输入时用0表示),能够用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽或然找好心程度高的同窗来协助传纸条,即找到来回两条传递路径,使得那两条路线上同学的好意程度只和最大。今后,请您扶助小渊和小轩找到那样的两条途径。

输入描述 Input Description

输入的第三行有三个用空格隔开的整数m和n,表示班里有m行n列(1<=m,n<=50)。

接下去的m行是3个m*n的矩阵,矩阵中第i行j列的平头表示坐在第i行j列的学习者的好意程度。每行的n个整数之间用空格隔开。

出口描述 Output Description

出口共一行,包括一个整数,表示过往两条路上参预传递纸条的学习者的美意程度之和的最大值。

样例输入 萨姆ple Input

3 3

0 3 9

2 8 5

5 7 0

样例输出 萨姆ple Output

34

数码范围及提醒 Data Size & Hint

百分之三十的数码知足:1<=m,n<=10

百分之百的多少满足:1<=m,n<=50

 

dfs(sb)T7,正解是dp

dfs(回想,恐怕剪枝不够或此题不可用dfs):

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define ll long long
 6 
 7 using namespace std;
 8 const int N=51;
 9 const int fistx[3]={0,1};
10 const int fisty[3]={1,0};
11 const int endx[3]={0,-1};
12 const int endy[3]={-1,0};
13 
14 ll a[N][N];
15 bool vis[N][N];
16 ll Answer;
17 ll answer;
18 ll n,m;
19 
20 ll read()
21 {
22     ll x=0;
23     char c=getchar();
24     while(c<'0'||c>'9')c=getchar();
25     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
26     return x;
27 }
28 
29 void dfs_2(int x,int y)
30 {
31     if(x==1&&y==1)
32     {
33         Answer=max(Answer,answer);
34         return ;
35     }
36     for(int i=0;i<=1;i++)
37     {
38         int xx=x+endx[i];
39         int yy=y+endy[i];
40         if(!vis[xx][yy]&&xx>=0&&xx<=n&&yy>=0&&yy<=m)
41         {
42             vis[xx][yy]=1;
43             answer+=a[xx][yy];
44             dfs_2(xx,yy);
45             vis[xx][yy]=0;
46             answer-=a[xx][yy];
47         }
48     }
49 }
50 
51 void dfs_1(int x,int y)
52 {
53     if(x==n&&y==m)
54     {
55         dfs_2(x,y);
56         return ;
57     }
58     for(int i=0;i<=1;i++)
59     {
60         int xx=x+fistx[i];
61         int yy=y+fisty[i];
62         if(!vis[xx][yy]&&xx>=0&&xx<=n&&yy>=0&&yy<=m)
63         {
64             vis[xx][yy]=1;
65             answer+=a[xx][yy];
66             dfs_1(xx,yy);
67             vis[xx][yy]=0;
68             answer-=a[xx][yy];
69         }
70     }
71 }
72 
73 int main()
74 {
75     freopen("message.in","r",stdin);
76     freopen("message.out","w",stdout);
77     
78     n=read();
79     m=read();
80     
81     for(int i=1;i<=n;i++)
82         for(int j=1;j<=m;j++)
83             a[i][j]=read();
84 
85     dfs_1(1,1);
86     printf("%d",Answer);
87     return 0;
88 }

正解dp:

 1 #include <cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 int n,m,a[51][51],f[51][51][51];
 8 
 9 int main() 
10 {
11     scanf("%d%d",&n,&m);
12     for (int i = 1 ; i <= n ; i ++ )
13         for (int j = 1 ; j <= m ; j ++ )
14             scanf("%d",&a[i][j]);
15             
16     for (int i = 1 ; i <= n ; i ++ ) 
17     {
18         for (int j = 2 ; j <= m ; j ++ ) 
19         {
20             for(int k = i + 1 ; k < i + j && k <= n ; k ++ ) 
21             {
22                 int l = i + j - k ;
23                 f[i][j][k] =  max( max(f[i-1][j][k],f[i-1][j][k-1]), max(f[i][j-1][k],f[i][j-1][k-1]));
24                 f[i][j][k] += ( a[i][j] + a[k][l] ) ;
25             }
26         }
27     }
28     printf("%d",f[n-1][m][n]) ;
29 }

 

相关文章

网站地图xml地图