悦动达人
Description
一个游戏,在屏幕上有5个格子形成一行,每一秒都会有一个格子闪烁,格子闪烁时你需要保证至少有一只手指在格子上面, 现在我们已经知道第i秒时,第xi个格子会闪烁,我们假设手指的移动不花费时间,你现在用两根手指玩这个游戏, 设初始两根手指都在0处位置,算出n秒过后手指需要移动的最小距离。(允许手指交叉)
注:手指移动的距离的计算是,假设你的一根从x,移动到y格,那么移动的距离是|x-y|
Input
第一行一个数T,表示有T组测试数据(T<=50) 第二行,n,表示进行n秒(1<=n<=10^4) 下一行 n个数,xi(0<=xi<=4)
Output
输出n秒过后手指需要移动的最小距离.
Sample Input
1 2 0 2
Sample Output
2
HINT
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 const int inf = 0x3f3f3f3f ; 5 int T ; 6 int n ; 7 int x ; 8 int a[10 + 10000][5][5] ; 9 10 void init () 11 { 12 for (int i = 0 ; i <= n ; i++ ) { 13 for (int j = 0 ; j < 5 ; j++ ) { 14 for (int k = 0 ; k < 5 ; k++ ) { 15 a[i][j][k] = inf ; 16 } 17 } 18 } 19 a[0][0][0] = 0 ; 20 } 21 22 int solve () 23 { 24 int x ; 25 for (int i = 1 ; i <= n ; i++) { 26 scanf ("%d" , &x ) ; 27 for (int j = 0 ; j < 5 ; j++ ) { 28 for (int k = 0 ; k < 5 ; k++ ) { 29 a[i][j][k] = a[i - 1][j][k] ; 30 // printf ("%-10d " , a[i][j][k]) ; 31 } 32 // puts ("") ; 33 } 34 // puts ("") ; 35 for (int j = 0 ; j < 5 ; j++ ) { 36 for (int k = 0 ; k < 5 ; k++ ) { 37 if (a[i - 1][j][k] + fabs (j - x) < a[i][x][k]) { 38 a[i][x][k] = a[i - 1][j][k] + fabs (j - x) ; 39 } 40 if (a[i - 1][j][k] + fabs (k - x) < a[i][j][x]) { 41 a[i][j][x] = a[i - 1][j][k] + fabs (k - x) ; 42 } 43 if (j - x != 0 && k - x != 0) { 44 a[i][j][k] = inf ; 45 } 46 } 47 } 48 } 49 /* for (int i = 0 ; i < 5 ; i++) { 50 for (int j = 0 ; j < 5 ; j++) { 51 printf ("%-10d " , a[n][i][j]) ; 52 } 53 puts ("") ; 54 } 55 puts ("") ; */ 56 } 57 58 int main () 59 { 60 // freopen ("a.txt" , "r" , stdin ) ; 61 scanf ("%d" , &T ) ; 62 while (T--) { 63 scanf ("%d" , &n ) ; 64 init () ; 65 solve () ; 66 int minn = inf ; 67 for (int i = 0 ; i < 5 ; i++) { 68 for (int j = 0 ; j < 5 ; j++) { 69 if (a[n][i][j] < minn) { 70 minn = a[n][i][j] ; 71 } 72 } 73 } 74 printf ("%d " , minn ) ; 75 } 76 return 0 ; 77 }
第一道手刃的多维dp。
一开始还以为这倒也可以用省空间的写法写,但果断orz
总体来说写的蛮顺利。