時間限制: 1 sec 記憶體限制: 128 mb
提交: 33 解決: 17
[提交][狀態][討論版]
假設我們將序列中第i件物品的引數定義為ai,那麼排序就是指將a1,…,an從小到大排序。若 i < j 且 ai > aj,則 < i , j > 就為乙個「逆序對」。sort公司是乙個專門為使用者提供排序服務的公司,他們的收費標準就是被要求排序物品的「逆序對」的個數,簡稱「逆序數」。grant是這家公司的排序員,他想知道對於n個引數都不同的物品組成的序列集合中,逆序對數為t的物品序列有多少個,並試給出其中乙個最小的物品序列。所謂 最小,即若有兩個物品序列(a1,a2,…,an),(b1,b2,…,bn),存在1≤i≤n,使得(a1,a2,…,ai-1)=(b1,b2,…,bi-1)且ai<bi。
只有一行,該行只有兩個整數n和t (1≤n≤20,0≤t≤n*(n-1)/2 )。
有二行,第一行只有乙個數,表示n個引數都不同的物品組成的序列集合中,逆序數為t的序列個數;第二行是所求物品引數序列。假設n個物品的引數分別為1到n。每個數字後面有乙個空格,包括最後乙個數字。
4 3
61 4 3 2
解析:第一小問動歸解決;
第二小問只交換相鄰兩數達到使逆序對只加一的目的。
時間複雜度o(
tn)
#include
#include
inti,j,k,n,t,p;
longlongf[
21][
211];
intans[
21];
shortrec[
21];
intswap
(int&a,int&b)
intmain()
f[2][
1]=1; f[2][
0]=1;
for(i=
3; i<=n; i++)
for(j=
0; j<=i*(i
-1)/
2; j++)
for(k=
0; k
if(j>=k)
f[i][j]+=f[i
-1][j-k];
printf
("%lld\n"
,f[n][t]);
for(i=
1; i<=n; i++)
ans[i]=i;
for(i=
1; i<=t; i++)
inta=p
-1,b=rec[ans[p
-1]+1];
swap(a,b);
}for(i=
1; i<=n; i++)
printf
("%d "
,ans[i]);
return0;
} 第一小問動歸解決;
第二小問只交換相鄰兩數達到使逆序對只加一的目的。
時間複雜度o(
tn)#include
#include
inti,j,k,n,t,p;
longlongf[
21][
211];
intans[
21];
shortrec[
21];
intswap
(int&a,int&b)
intmain()
f[2][
1]=1; f[2][
0]=1;
for(i=
3; i<=n; i++)
for(j=
0; j<=i*(i
-1)/
2; j++)
for(k=
0; k
if(j>=k)
f[i][j]+=f[i
-1][j-k];
printf
("%lld\n"
,f[n][t]);
for(i=
1; i<=n; i++)
ans[i]=i;
for(i=
1; i<=t; i++)
inta=p
-1,b=rec[ans[p
-1]+1];
swap(a,b);
}for(i=
1; i<=n; i++)
printf
("%d "
,ans[i]);
return0;
}
P2528 SHOI2001 排序工作量之新任務
假設我們將序列中第i件物品的引數定義為ai,那麼排序就是指將a1,an從小到大排序。若iaj,則就為乙個 逆序對 sort公司是乙個專門為使用者提供排序服務的公司,他們的收費標準就是被要求排序物品的 逆序對 的個數,簡稱 逆序數 grant是這家公司的排序員,他想知道對於n個引數都不同的物品組成的序...
(1)排序之氣泡排序
氣泡排序是一種交換排序。什麼是交換排序呢?交換排序 兩兩比較待排序的關鍵字,並交換不滿足次序要求的那對數,直到整個表都滿足次序要求為止。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算...
(6)排序之堆排序
文章 靜默空間 堆的概念 在介紹堆排序之前,首先需要說明一下,堆是個什麼玩意兒。堆是一棵順序儲存的完全二叉樹。其中每個結點的關鍵字都不大於其孩子結點的關鍵字,這樣的堆稱為小根堆。其中每個結點的關鍵字都不小於其孩子結點的關鍵字,這樣的堆稱為大根堆。舉例來說,對於n個元素的序列當且僅當滿足下列關係之一時...