Theme
For example, this is a dance machine. In the initial state, both the feet are 0 and the status is (0, 0). Then, the dance opportunity gives you a series of dance directions, such, 3 .......
Each time you have to select a foot to move to each grid in the corresponding numeric direction.
For example, to move from the initial status () to 1, you can select the Left or Right foot to move up, the corresponding status is (1, 0)
There is a limit, except that the initial status can be (0, 0), and the subsequent two feet can no longer be on a grid at the same time!
It takes physical strength to move the foot. Moving from 0 to other places consumes 2, from 1, 2, 3, and 4. If it is to move to an adjacent grid, such as 1-> 2, 1-> 4, 3-> 2, 4-> 3, consuming physical strength 3
If it is to move to the opposite lattice, such as 1-> 3, 2-> 4, it consumes 4 of the physical strength.
If one step stops and does not move, it consumes 1
For a string of directions, how much physical energy can be used to complete these actions?
Ideas
F (I, j, k) indicates step I, the minimum physical strength required when the status is (j, k)
It is not difficult to introduce the transfer equation:
Assuming that the current step is in s, all the statuses that match this step are:
F (I, 0 .. 4, s), f (I, s, 0... 4)
Then we can roll out the minimum physical call fees for the next step based on the above status.
Assume that the next step is next.
So
If f (I, j, s), (0 <= j <= 4) status is reachable
The next status is available.
F (I + 1, j, s) = f (I, j, k) + 1; // stop
F (I + 1, next, s) = min {f (I, j, s) + consume (j, next )}
F (I + 1, j, next) = min {f (I, j, s) + consume (s, next )}
Similarly, if f (I, s, j) and (0 <= j <= 4) are reachable
You can also release the following status:
F (I + 1, s, j) = f (I, j, k) + 1; // stop
F (I + 1, next, j) = min {f (I, s, j) + consume (s, next )}
F (I + 1, s, next) = min {f (I, s, j) + consume (j, next )}
Code
/**========================================== * This is a solution for ACM/ICPC problem * * @source:uva-1291 Dance Dance Revolution * @author: shuangde * @blog: blog.csdn.net/shuangde800 * @email: zengshuangde@gmail.com *===========================================*/#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<cmath>#include<cstring>using namespace std;typedef long long int64;const int INF = 0x3f3f3f3f;const int MAXN = 10010;int n;int dir[MAXN];int f[MAXN][5][5];inline int consume(int from, int to){ if(from==to) return 1; if(from==0 || to==0) return 2; int res = abs(from-to); if(res == 1 || res==3) return 3; if(res == 2) return 4;}int main(){ while(~scanf("%d", &dir[0]) && dir[0]){ n = 1; while(~scanf("%d", &dir[n]) && dir[n]) ++n; memset(f, INF, sizeof(f)); for(int i=0; i<=4; ++i) f[0][0][i] = f[0][i][0] = consume(0, i); for(int i=0; i<n-1; ++i){ int s = dir[i]; int next = dir[i+1]; for(int j=0; j<=4; ++j) if(s!=j){ if(f[i][s][j] != INF){ f[i+1][s][j] = min(f[i+1][s][j], f[i][s][j] + 1); for(int k=0; k<=4; ++k){ f[i+1][next][j] = min(f[i+1][next][j], f[i][s][j] +consume(s, next)); f[i+1][s][next] = min(f[i+1][s][next], f[i][s][j] +consume(j, next)); } } if(f[i][j][s] != INF){ f[i+1][j][s] = min(f[i+1][j][s], f[i][j][s] + 1); for(int k=0; k<=4; ++k){ f[i+1][next][s] = min(f[i+1][next][s], f[i][j][s] +consume(j, next)); f[i+1][j][next] = min(f[i+1][j][next], f[i][j][s] +consume(s, next)); } } } } int ans = INF; int s = dir[n-1]; for(int i=0; i<=4; ++i)if(i!=s){ ans = min(ans, min(f[n-1][i][s], f[n-1][s][i])); } printf("%d\n", ans); } return 0;}