NYOJ 61(传纸条)

 

NYOJ 61 传纸条是一个双线DP的题:

从矩阵的左上角(1,1)点到矩阵的右下角(m,n)点找到两条不相交的路径使其值最大,

题中是从(1,1)到(m,n)走一次,再从(m,n)到(1,1)走一次,我们可以等价变形

一下,变为:同时从(1,1)走向(m,n)找两条路,且这两条路不相交,同时走!

假设有两个人在走,一个人的坐标为(x1,y1),另一个人的坐标为(x2,y2),有题中规定

只能向下或向右走,则可得状态转移方程:

f(x1,y1,x2,y3)  =  max { f(x1-1,y1,x2-1,y2)  ,f(x1-1,y1,x2,y-1),  f(x1,y1-1,x2-1,y2),  f(x1,y1-1,x2,y2-1)} + map[x1][y1] + map[x2][y2]

(map中存放同学的好心度,相当于权值)

 

这样写的话  时间复杂度会是O(n^4),比较大容易超时,改进:

因为 两个人是同时走的所以 每次都是同时移动一格:因此有   x1+y1==x2+y2 == k

则状态方程可以改为:

 

f(k,x1,x2) = ma{  f(k-1,x1,x2),  f(k-1,x-1,x2) ,f(k-1,x1,x2-1),  f(k-1,x1-1,x2-1)  }  + map[x1][k-x1] + map[x2][k-x2]

 

本题代码:

 

 

View Code
 1  
 2 #include<stdio.h>
 3 #include<string.h>
 4 
 5 int a[201][101][101];
 6 int map[101][101];
 7 
 8 int max(int n1,int n2,int n3,int n4)
 9 {
10    int s,d;
11    s = n1>n2?n1:n2;
12    d = n3>n4?n3:n4;
13    s = s>d?s:d;
14    return s;
15 }
16 
17 int slove(int m,int n)
18 {
19   int x1,y1,x2,y2,k;
20   for(k=2;k<=m+n;++k)
21    for(x1=1;x1<=m;++x1)
22     for(x2=1;x2<=m;++x2)
23      {
24        y1=k-x1;
25        y2=k-x2;
26        if(y1<0 || y2<0 || y1>n || y2>n)continue;
27        if(y1==y2)continue;
28        a[k][x1][x2]=max(a[k-1][x1][x2],a[k-1][x1-1][x2],
29                         a[k-1][x1][x2-1],a[k-1][x1-1][x2-1])
30                         +map[x1][y1]+map[x2][y2];
31      }
32    return a[m+n-1][m][m-1];
33 }
34 
35 int main()
36 {
37   int t,m,n,i,j;
38   scanf("%d",&t);
39   while(t--)
40   {
41     memset(a,0,sizeof(a));
42     scanf("%d%d",&m,&n);
43     for(i=1;i<=m;++i)
44      for(j=1;j<=n;++j)
45       scanf("%d",&map[i][j]);
46     printf("%d\n",slove(m,n));
47   }
48   return 0;
49 }
50 
51         

 

posted @ 2012-04-09 17:10  知行执行  阅读(707)  评论(0编辑  收藏  举报