zz是一位大理石收藏家,他在家裡收藏了n塊各種顏色的大理石,第i塊大理石的顏色為ai。但是zz覺得這些石頭在家裡隨意擺放太過凌亂,他希望把所有顏色相同的石頭放在一起。換句話說,zz需要對現有的大理石重新進行排列,在重新排列之後,對於每乙個顏色j,如果最左邊的顏色為j的大理石是第l塊大理石,最右邊的顏色為j的大理石是第r塊大理石,那麼從第l塊大理石到第r塊大理石,這些石頭的顏色都為j。
由於這些大理石都比較重,zz無法承受這些大理石的重量太久,所以他每次搬運只能交換相鄰的兩塊大理石。請問,zz最少需要進行多少次搬運?
第一行輸入乙個數字n(2≤n≤4*10^5),表示大理石的總數。
第二行輸入n個數字a1,a2…,an(1≤ai≤20)表示第i塊大理石的顏色為ai。
輸出zz最少需要搬運的次數。
n很大,但是顏色少啊,很明顯的乙個狀壓dp的題,狀態的表示0即為當前
位置的顏色沒有完成,1則表示為完成了
定義乙個陣列表示g[25
][25]
g[25][25]
g[25][
25]表示i號顏色前j號顏色一共有多少個,
d p[
i]=m
in(d
p[i]
,dp[
i−j]
+cos
t(i,
j)
)dp[i]=min(dp[i],dp[i-j]+cost(i,j))
dp[i]=
min(
dp[i
],dp
[i−j
]+co
st(i
,j))
#include #include using namespace std;
#define int long long
int n;
int a[400005];
int cost[400005][25]; // i為前顏色為j有多少個
int c[25][25]; //表示第i個顏色前有多少個j顏色
int dp[(1 << 21)];
int solve_cost(int col, int t)
return ans;
}signed main()
for (int i = 1; i <= n; i++)
for (int i = 1; i <= n; i++)
}memset(dp, 127, sizeof(dp));
dp[0] = 0;
for (int i = 1; i <= (1 << 20); i++) }}
cout << dp[(1 << 20) - 1];
return 0;
}
週末訓練 大理石
記憶體限制 256 mib 時間限制 4000 ms 標準輸入輸出 題目型別 傳統 評測方式 文字比較 林老師是一位大理石收藏家,他在家裡收藏了 n 塊各種顏色的大理石,第 i 塊大理石的顏色為 a i 但是林老師覺得這些石頭在家裡隨意擺放太過凌亂,他希望把所有顏色相同的石頭放在一起。換句話說,林老...
週末訓練 大理石
記憶體限制 256 mib 時間限制 4000 ms 標準輸入輸出 題目型別 傳統 評測方式 文字比較 林老師是一位大理石收藏家,他在家裡收藏了 n 塊各種顏色的大理石,第 i 塊大理石的顏色為 a i 但是林老師覺得這些石頭在家裡隨意擺放太過凌亂,他希望把所有顏色相同的石頭放在一起。換句話說,林老...
大理石在哪兒
現有n各大理石,每個大理石上寫著乙個非負整數。首先把各數從小到大排序,然後回答q各問題。每個問題問是否有乙個大理石寫著某個整數x,如果是,還要回答哪個大理石上寫著x。排序後的大理石從左到右編號為1 n。樣例輸入 4 11 3 5 1 55 2 1 3 3 3 1 2 3樣例輸出 case 1 5 f...