3049 舞蹈家懷特先生
阿新 • • 發佈:2017-05-27
例如 動態 small ans mov str turn int 來安
每一個時刻,它必須移動而且只能移動他的一只腳去踩相應的箭頭,而另一只腳不許移動。跳完一首曲子之後,懷特先生會計算他所消耗的體力。從中心移動到任何一個箭頭耗費2單位體力,從任何一個箭頭移動到相鄰箭頭耗費3單位體力,移動到相對的箭頭(1和3相對,2和4相對)耗費4單位體力,而留在原地再踩一下只需要1單位。懷特先生應該怎樣移動他的雙腳(即,對於每個箭頭,選一只腳去踩它),才能用最少的體力完成一首給定的舞曲呢?
例如,對於箭頭序列Left (2), Left (2), Up (1), Right (4),他應該分別用左、左、右、右腳去踩,總的體力耗費為2+1+2+3=8單位。 輸入描述 Input Description
f[i][a[i]][k] = min(f[i][a[i]][k],f[i-1][j][k]+move(a[i],j));(j,k∈(0,4))
3049 舞蹈家懷特先生
時間限制: 1 s 空間限制: 64000 KB 題目等級 : 黃金 Gold 題目描述 Description
懷特先生是一個大胖子。他很喜歡玩跳舞機(Dance Dance Revolution, DDR),甚至希望有一天人家會腳踏“舞蹈家懷特先生”。可惜現在他的動作根本不能稱作是在跳舞,盡管每次他都十分投入的表演。這也難怪,有他這樣的體型,玩跳舞機是相當費勁的。因此,他希望寫一個程序來安排舞步,讓他跳起來輕松一些,至少不要每次都汗流浹背。
DDR的主要內容是用腳來踩踏板。踏板有四個方向的箭頭,用1 (Up)、2 (Left)、3 (Down)、4 (Right)來代表,中間位置由0來代表。每首歌曲有一個箭頭序列,遊戲者必須按照或這個序列一次用某一只腳踩相應的踏板。在任何時候,兩只腳都不能在同一踏板上,但可以同時待在中心位置0。
例如,對於箭頭序列Left (2), Left (2), Up (1), Right (4),他應該分別用左、左、右、右腳去踩,總的體力耗費為2+1+2+3=8單位。 輸入描述 Input Description
第一行N,表示有N個時刻 1<=N<=10000
第二到n+1行,每行一個數,表示需要踩得版
一個數,最小消耗體力
樣例輸入 Sample Input2
1
1
樣例輸出 Sample Output3
數據範圍及提示 Data Size & Hintn<=10000
動態規劃,f[k][i][j] 表示跳了k布,左腳在i,右腳在j,的最小步數,
所以分兩種情況,要麽左腳踩,要麽右腳踩,
f[i][j][a[i]] = min(f[i][j][a[i]],f[i-1][j][k]+move(a[i],k));
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 int f[10010][5][5]; 8 int a[10010]; 9 int n,m,ans=99999999; 10 11 int move(int a,int b) 12 { 13 if(a==b) return 1; 14 if(a==0||b==0) return 2; 15 if(a%2==b%2) return 4; 16 return 3; 17 } 18 19 int main() 20 { 21 scanf("%d",&n); 22 for (int i=1; i<=n; ++i) 23 scanf("%d",&a[i]); 24 memset(f,0x3f,sizeof(f)); 25 f[0][0][0] = 0; 26 for (int k=1; k<=n; ++k) 27 for (int i=0; i<=4; ++i) 28 for (int j=0; j<=4; ++j) 29 { 30 f[k][i][a[k]] = min(f[k][i][a[k]],f[k-1][i][j]+move(a[k],j)); 31 f[k][a[k]][j] = min(f[k][a[k]][j],f[k-1][i][j]+move(a[k],i)); 32 } 33 for (int i=0; i<=4; ++i) 34 for (int j=0; j<=4; ++j) 35 ans = min(ans,f[n][i][j]); 36 printf("%d",ans); 37 return 0; 38 }
3049 舞蹈家懷特先生