EOJ:Crisis on the Farm

Crisis on the Farm

Time Limit: 1000MS Memory Limit: 65536K
Total Submits: 111 Accepted: 18

Description

Farmer John and his herd of exotic dancing bovines have been practicing for his new moosical, "The Street Cow Named Desire". At one point in the middle of rehearsal, his cows are stacked on top of each other in N (1 <= N <= 1,000) sets of 30, one cow standing on the back of the other (they are quite amazing cows). Thus, the pasture is dotted with both these stacks of 30 cows and also, in separate locations, M (1 <= M <= 1,000) haystacks. Below is a sample of one way they might be laid out:
8 .........
7 ....CH.H. C = stack of 30 cows
6 .........
5 ......... H = haystack
4 ..C.HH...
3 .........
2 .....C.HH
1 .........
123456789

As the musical's conductor, Farmer John has four whistles with various tones. One whistle commands the cow at the bottom of each stack to move (along with all the stacked cows) one unit north, another indicates a move to the south, one indicates a move to the east, and a fourth to order a move to the west.

Any time the stack of cows enters a grid location with a haystack, the cow on the top of the stack (even if the stack has height one) will jump onto the haystack while the remaining cows move into the same location as the haystack. Thus, if the bottom cow encounters 30 haystacks (perhaps different haystacks, perhaps not), the stack of 30 cows is exhausted with all the cows standing on top of haystacks (or standing on cows on haystacks). The sturdy haystacks can each support an unlimited number of cows.

Farmer John glances across his pasture to Farmer Don's milking facility to see, to his horror, a huge milk tank exploding and unleashing a giant tidal wave of milk making its way toward the performing cows! Since any cows on a haystack are safe, FJ must now do what he can to save the lives of as many cows as possible using what has turned from a simple dance routine into a lifesaving technique.

Given the number of times K (1 <= K <= 30) farmer John can blow a whistle until the wave of milk crashes over the pasture and also the X_i, Y_i positions (1 <= X_i <= 1,000; 1 <= Y_i <= 1,000) of the N stacks of cows and M haystacks (none of which currently has any cows on it), report the greatest number of cows that can be saved and find a sequence of whistle blows that does the job. The sequence should be reported in terms of the four directions, 'E' for east, 'N' for north, 'W' for west, 'S' for south. Among all such sequences, farmer John wants the lexicographically least. Initial locations of cows and haystacks will not share the same coordinates in the input.

Cows can be moved to any location, including ones outside the pasture.

 

Input

* Line 1: Three space-separated integers: N, M, and K
* Lines 2..N+1: Line i+1 describes the X,Y location of a stack of 30 cows using two space-separated integers: X_i and Y_i
* Lines N+2..N+M+1: Line i+N+1 describes the X,Y location of a haystack using two space-separated integers: X_i and Y_i

 

Output

* Line 1: A single integer that is the most number of cows that can be saved.
* Line 2: K characters, the lexicographically least sequence of commands FJ should issue to maximize the number of cows saved.

 

Sample Input

3 6 33 46 25 78 29 26 45 46 78 7

Sample Output

6
EEE

原题地址:http://www.cn210.com/onlinejudge/problemshow.php?pro_id=180

________________________________________________________________________________________________________

 

题解:

一开始完全没有想法。

一个很重要的条件是,牛的动作是统一的!那么就看做只有一堆牛,这堆牛走一步能获救的数量就等于原来那么多堆牛同时走一步能获救的数量和。

  

只用考虑第一叠奶牛的状态,之后的奶牛的位置都可以知道。
我们用Get[i][j]表示第一叠奶牛现在在点(x1+i,y1+j),通过任一个方向移动过来,所新拯救的奶牛。
我们可以想到用dp[i][j][t]表示第一叠奶牛现在在点(x1+i,y1+j),且一共走了t步所拯救的奶牛。
dp[i][j][t]=max(f[i+dx[w],j+dy[w]][t-1])+G[i][j]。

 

动归方程有了,还有一个问题是动归的顺序问题,即:有的点知道后才能更新其他点,那么动归岂不是要从DP[X1][Y1][0]开始做?其实不用,我们可以把t=0时想象成一幅图,T=1时想象成一幅图……这样就有30幅图。对于每一幅图上的点,只能由上一幅图上已经存在的点来更新,这样就不需要考虑从哪个点开始更新。

 

代码:

这里选取的是(30,30)这个点作为那一叠奶牛,这样动归就可以从(0,0)点开始做了,因为最多走30步。

代码
1 /*将奶牛缩成一个点
2 t取不同值时,看作不同的图,在图上进行二维动归,用已知的点去更新四周的点。因为此时时间相同,因此不需要考虑先后顺序的问题
3 例如
4 t=1
5 .......
6 .......
7 ...*...
8 .......
9 由中间的点更新四周的点,无论是从左上角开始扫还是从其他地方开始都无所谓
10  */
11 #include<stdio.h>
12 #include<string.h>
13 int dx[4]={1,0,0,-1};
14 dy[4]={0,1,-1,0};
15 int n,m,t,i,j,k,x,y,nowx,nowy,max,l,tx,ty;
16 int dp[64][64][32];
17 int get[64][64],map[1002][1002];
18 char path[64][64][32][32],ans[32];
19 struct edge
20 {
21 int x,y;
22 }cow[1002];
23 int main()
24 {
25 scanf("%d%d%d",&n,&m,&t);
26 for (i=1;i<=n;i++)
27 scanf("%d%d",&cow[i].x,&cow[i].y);
28 for (i=1;i<=m;i++)
29 {
30 scanf("%d%d",&x,&y);
31 map[x][y]=1;
32 }
33 x=30;
34 y=30;
35 for (i=x-t;i<=x+t;i++)
36 for (j=y-t;j<=y+t;j++)
37 {
38 tx=i-x;
39 ty=j-y;
40 get[i][j]=0;
41 for (k=1;k<=n;k++)
42 {
43 nowx=cow[k].x+tx;
44 nowy=cow[k].y+ty;
45 if (nowx>=0&&nowx<=1000&&nowy>=0&&nowy<=1000&&map[nowx][nowy]==1)
46 get[i][j]++;
47 }
48 }
49 for (i=0;i<=62;i++)
50 for (j=0;j<=62;j++)
51 for (k=0;k<=t;k++)
52 dp[i][j][k]=-2147483646;
53 dp[x][y][0]=0;
54 for (k=1;k<=t;k++)
55 {
56 ;
57 for (i=x-t;i<=x+t;i++)
58 for (j=y-t;j<=y+t;j++)
59 for (l=0;l<4;l++)
60 {
61 nowx=i+dx[l];
62 nowy=j+dy[l];
63 if (nowx>=0&&nowx<=62&&nowy>=0&&nowy<=62)
64 if (dp[nowx][nowy][k]<dp[i][j][k-1]+get[nowx][nowy])
65 {
66 strcpy(path[nowx][nowy][k],path[i][j][k-1]);
67 dp[nowx][nowy][k]=dp[i][j][k-1]+get[nowx][nowy];
68 switch (l)
69 {
70 case 0:strcat(path[nowx][nowy][k],"E");break;
71 case 1:strcat(path[nowx][nowy][k],"N");break;
72 case 2:strcat(path[nowx][nowy][k],"S");break;
73 case 3:strcat(path[nowx][nowy][k],"W");break;
74 }
75 }
76 else
77 if (dp[nowx][nowy][k]==dp[i][j][k-1]+get[nowx][nowy])
78 if(strcmp(path[i][j][k-1],path[nowx][nowy][k])<0)
79 {
80 strcpy(path[nowx][nowy][k],path[i][j][k-1]);
81 switch (l)
82 {
83 case 0:strcat(path[nowx][nowy][k],"E");break;
84 case 1:strcat(path[nowx][nowy][k],"N");break;
85 case 2:strcat(path[nowx][nowy][k],"S");break;
86 case 3:strcat(path[nowx][nowy][k],"W");break;
87 }
88 }
89 }
90 }
91 max=0;
92 for (i=x-t;i<=x+t;i++)
93 for (j=y-t;j<=y+t;j++)
94 if (dp[i][j][t]>max)
95 {
96 max=dp[i][j][t];
97 strcpy(ans,path[i][j][t]);
98 }
99 else
100 if (dp[i][j][t]==max&&strcmp(ans,path[i][j][t])>0)
101 strcpy(ans,path[i][j][t]);
102 printf("%d\n",max);
103 printf("%s\n",ans);
104 return 0;
105 }

 

posted on 2010-07-28 13:33  风也轻云也淡  阅读(275)  评论(0编辑  收藏  举报