description
rita喜歡玩跳舞毯。但每次跳完都汗流浹背,於是她希望寫乙個程式安排她的舞步,使自己跳起來輕鬆一點。
跳舞毯的主要內容是用腳來踩踏板。踏板有4個方向的箭頭,用1,2,3,4來代表上左下右,0代表中間位置。
每首歌有乙個箭頭序列,rita必須按照這個序列依次用某乙隻腳踩相應的踏板。每乙個時刻,rita必須移動而且只能移動她的乙隻腳去踩相應的箭頭,而另乙隻腳不許移動,跳完一首曲子之後,rita會計算她所消耗的體力。從中心移動到任何乙個箭頭消耗2點體力值,從任何乙個箭頭移動到相鄰的箭頭消耗3點體力值,移動到相對的箭頭(1和3、2和4相對)消耗4點體力值,在原地再踩一下消耗1點體力值。rita怎樣移動她的雙腳(對於每乙個箭頭選擇乙隻腳去踩它)才能用最少的體力消耗完成一首給定的舞曲呢?
input
輸入資料第一行是乙個整數t。下面由t組測試資料組成,每組測試資料佔二行,第一行有1個整數n(1 <= n <= 1000000)代表一首曲子有n個箭頭,第二行有n個整數ai(1 <= ai <= 4)分別代表上左下右箭頭,其實雙腳均在中間位置。
output
對於每個資料,輸出1個整數代表最小體力消耗,每個資料的輸出佔一行。
sample input14
2 2 1 4
sample output
這是道簡單dp,不過狀態有點多,比較麻煩。
設dp [5] [5] [n] 陣列,第一維表示左腳狀態,第二維表示右腳狀態,第三維表示箭頭序號(當前在踩第幾個箭頭)。
設arr[n]陣列為箭頭序列。
於是便能起草這麼個狀態轉移方程:
dp[a][b][i] = min[dp[a][b][i - 1] + cost](a = 0 ~ 5, b = 0 ~ 5)(a == arr[i] || b == arr[i])
其中cost為上乙個狀態(左腳為a,右腳為b時)轉移到當前狀態(左腳為a,右腳為b時)所消耗的體力值。
再考慮邊界情況,新增點細枝末節,寫出**
#include
#include
#include
#include
using
namespace std;
int dp[5]
[5][
1000001];
const
int maxn =
0x3f3f3f3f
;int
main
(void)}
}int ans = maxn;
for(
int a =
0; a <5;
++a)
for(
int b =
0; b <5;
++b)
ans =
min(ans, dp[a]
[b][n]);
cout << ans;
}}
然後就會發現記憶體不夠了哈哈。
仔細觀察能發現,當前狀態只由上乙個狀態決定,再之前的就無關了,於是dp陣列可以壓縮到二維,用滾動陣列的方式。
#include
#include
#include
#include
using
namespace std;
int dp[5]
[5][
2];const
int maxn =
5000000
;int
main
(void)}
}int ans = maxn;
for(
int a =
0; a <5;
++a)
for(
int b =
0; b <5;
++b)
ans =
min(ans, dp[a]
[b][
(n +1)
%2])
; cout << ans;
}}
然後就會發現超時了,哈哈。
再仔細觀察還能發現當前狀態兩隻腳都不為箭頭的時候是不用考慮的,直接置無窮大。
於是可以進一步壓縮,再稍微優化一下,得如下狀態轉移方程:
dp[a][arrow][1] = min[dp[a][b][0] + cost](a = 0 ~ 5, b = 0 ~ 5)
再稍微優化一下,得如下ac**
#include
#include
#include
#include
using
namespace std;
int dp[5]
[5][
2];const
int maxn =
0x3f3f3f3f
;int
main
(void
)for
(int a =
0; a <5;
++a)
for(
int b =
0; b <5;
++b)
dp[a]
[b][
(i +1)
%2]= maxn;
}int ans = maxn;
for(
int a =
0; a <5;
++a)
for(
int b =
0; b <5;
++b)
ans =
min(ans, dp[a]
[b][
(n +1)
%2])
; cout << ans << endl;
}}
廈門理工學院OJ題解(1513 最大D)
description 美麗的黃靜雯學姐將一副卡牌隨機擺成一排,已知只有數字 1 9 和字母 a z 兩類卡牌。對給定長度為n的卡牌序列串s n 100 學姐想按如下規則得到數字卡牌序列串d 1 每次只能從s的頭部或者尾部取一張數字卡牌新增到d末尾 2 s中的字母卡牌不能新增到d末尾,直接將它從s拿...
廈門理工學院OJ題解(1501 養生的學長)
description input 第一行輸入乙個正整數n 0 n 10 代表作業的數量 第二行輸入n個正整數ai以空格相隔,代表接下來要順序完成的每項作業所需的時間 0 ai 10 輸入的測試資料保證一定能夠完成作業 output 輸出乙個整數k代表最少需要的牛奶糖數 sample input 5...
廈門理工學院OJ題解(1139 秦心的面具)
秦心由面具所轉化而成的付喪神。因為本體總是木無表情,看上去就像乙個三無少女。持有66個代表不同情緒的面具,通過這些面具可以表達出不同的感情。擁有操控感情程度的能力。秦心無意之中丟失了代表 希望 的面具,因此面具之間微妙的力量平衡被打破了。秦心在人間之里遇到了撿到希望之面的古明地戀 以下簡稱戀戀 然而...