有一个跳舞机。原点为0,有四个方向,上左下右,分别标成(1234),初始玩家两只脚站在 0 位置,跳舞机会给出一串数字,玩家要按照顺序踩下四个方向的数字。移动脚会消耗玩家的能量,从0位置移动到四个方向消耗2点能量,从一个方向移动到另一个相邻的方向消耗3点能量,从一个方向移动到相反方向消耗4点能量,原点踩一下消耗1点能量。问你踩出这串数子最少要花多少能量。
根据能量消耗关系,我们可以发现当前两只脚踩的方向才是重点。然而要记录两只脚的方向么?其实不用,因为我们可以发现两只脚的状态是互不影响的,而且单跳到第i个数字的时候,有一只脚的位置是确定的。
然后在dp[n][*]里面找个最小值。
#include <bits/stdc++.h> using namespace std; const int INF = 999999999; int k; int a[100010]; int _read() { int tmp; for ( k=1; scanf("%d", &tmp) && tmp; ) {// cout << tmp << endl; a[k++] = tmp; } // a[k++] = tmp; return k; } int dp[100010][5]; int _get(int a, int b) { if (a == 0) return 2; if (a == b) return 1; if (abs(a-b) == 1 || abs(a-b) == 3) return 3; if (abs(a-b) == 2) return 4; } int main () {// cout << "*" << endl; for (; _read() != 1; ) {// cout << k << endl; for (int i=0; i<=k; i++) { fill(dp[i], dp[i]+5, INF); } dp[1][0] = _get(0, a[1]); for (int i=2; i<k; i++) { for (int j=0; j<=4; j++) { dp[i][j] = min(dp[i][j], dp[i-1][j] + _get(a[i-1], a[i])); dp[i][a[i-1]] = min(dp[i][a[i-1]], dp[i-1][j] + _get(j, a[i])); } } int ans = INF; for (int i=0; i<=4; i++) { ans = min(ans, dp[k-1][i]); } printf("%d\n", ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/xuelanghu407/article/details/47988559