悦动达人 (多维dp)

悦动达人

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 }
View Code

第一道手刃的多维dp。
一开始还以为这倒也可以用省空间的写法写,但果断orz

总体来说写的蛮顺利。

原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4345397.html