時間限制: 1 s
空間限制: 32000 kb
題目等級 : ** gold
題解有一列數,要對其進行排序(公升序)。排序只能通過交換來實現。每次交換,可以選擇這列數中的任意二個,交換他們的位置,並且交換的代價為二個數的和。排序的總代價是排序過程中所有交換代價之和。先要求計算,對於任意給出的數列,要將其排成公升序所需的最小代價。
輸入描述 input description
輸入資料有兩行組成。第一行乙個數n,表示這列數共有n個數組成,第二行n個互不相同的整數(都是小於1000的正整數),表示這列數
輸入可能包含多組測試資料(少於50組),對於每個輸入資料均需要給出對應的輸出
輸出描述 output description
對於每個輸入資料,輸出最小代價。格式為case t: min
其中t為資料的編號,從1開始,min為這個資料的最小代價
樣例輸入 sample input
3 2 1
8 1 2 4
樣例輸出 sample output
case 1: 4
case 2: 17
資料範圍及提示 data size & hint
n<=1000
分類標籤 tags 點此展開
置換群群論
題解:
置換群+離散化.
使乙個數列恢復遞增順序,那麼,他和他要到達的位置的數需要交換,這樣就形成了乙個置換.
對於乙個有向圈的置換,我們可以證明它的最小代價就是這個有向圈中 最小元素*(有向圈的大小-1)+其他數的和-最小元素.
1個大小為n的有向環,至少會進行n-1次交換才能成為n個1元環
當size=1,2 時,它顯然成立.
當size>2 時,每次交換1個元素會將圓圈拆成兩個互不相交的置換,一直拆下去需要拆n-1次.
然後還有乙個問題就是我們可以把乙個最小的數拉過來進行交換,這樣我們就需要的代價就是,用最小的和有向圈中最小的交換,再讓最小的*(有向圈大小-1)
這樣這道題就顯而易見了,至於不是連續的,我們可以離散化.
ac**:
#include#include#include
using
namespace
std;
const
int n=1e3+10
;int
n,cnt,ans,cas;
intr[n],a[n],b[n],c[n],s1;
intp[n][n],s[n],h[n];
bool
vis[n];
intmain()
for(int i=1;i<=cnt;i++)
if(!ans) break
; printf(
"case %d: %d\n
",++cas,ans);
}return0;
}
09 排序1 排序
09 排序1 排序 25 分 給定n 個 長整型範圍內的 整數,要求輸出從小到大排序後的結果。本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下 include include includeusing namespace std const int cutoff 1000...
09 排序1 排序
n個 長整型範圍內的 整數,要求輸出從小到大排序後的結果。資料2 11個不相同的整數,測試基本正確性 資料3 10 3個隨機整數 資料4 10 4個隨機整數 資料5 10 5個隨機整數 資料6 10 5個順序整數 資料7 10 5個逆序整數 資料8 10 5個基本有序的整數 資料9 10 5個隨機正...
09 排序1 排序
本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下 資料1 只有1個元素 資料2 11個不相同的整數,測試基本正確性 資料3 103個隨機整數 資料4 104個隨機整數 資料5 105個隨機整數 資料6 105個順序整數 資料7 105個逆序整數 資料8 105個基本有序的...