對於乙個數列,如果有ii>aj,那麼我們稱ai與aj為一對逆序對數。若對於任意乙個由1~n自然數組成的數列,可以很容易求出有多少個逆序對數。那麼逆序對數為k的這樣自然數數列到底有多少個?
第一行為兩個整數n,k。
寫入乙個整數,表示符合條件的數列個數,由於這個數可能很大,你只需輸出該數對10000求餘數後的結果。
樣例輸入
4 1樣例輸出
3樣例說明:
下列3個數列逆序對數都為1;分別是1 2 4 3 ;1 3 2 4 ;2 1 3 4;
測試資料範圍
30%的資料 n<=12
100%的資料 n<=1000,k<=1000
正解:dp(遞推)
解題報告:
這道題我居然沒能一眼秒。。。
令f[i][j]表示前i個數逆序對數為j的序列個數,考慮dp(遞推)。因為插入前i-1個數的時候方案已經得出了,我們需要插入第i個數獲得新的一些序列。
因為i比前面任何乙個數都要大,所以插在第幾位,就會比後面的數大,對於總逆序對產生貢獻。考慮貢獻大小,可以插在前i-1個數的最後面,那麼對於逆序對數沒有產生任何貢獻,所以就是從f[i-1][j]轉移過來,但是插在其他位置呢?如果插在i-2個數後面就是產生1的貢獻,所以是f[i-1][j-1]。。。最後i-1中總共i-1個數,所以新產生的貢獻最大為i-1。可以得到方程式:f[i][j]=∑f[i-1][j-k](0<=k
複雜度o(n^3)但是可以優化。因為每次用的是一段,所以字首和優化一下,沒必要每次重新統計。
1//it is made by jump~
2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include
13#ifdef win32
14#define ot "%i64d"
15#else
16#define ot "%lld"
17#endif
18using
namespace
std;
19 typedef long
long
ll;20
const
int maxn = 1011;21
const
int mod = 10000;22
intn,k;
23int f[maxn][maxn];//
f[i][j]表示前i個數逆序對為j個的序列數
2425 inline int
getint()
2634
35 inline void
work()47}
48 printf("%d"
,f[n][k]);49}
5051
intmain()
52
bzoj2431 HAOI2009 逆序對數列
對於乙個數列,如果有ii aj,那麼我們稱ai與aj為一對逆序對數。若對於任意乙個由1 n自然數組成的數列,可以很容易求出有多少個逆序對數。那麼逆序對數為k的這樣自然數數列到底有多少個?第一行為兩個整數n,k。寫入乙個整數,表示符合條件的數列個數,由於這個數可能很大,你只需輸出該數對10000求餘數...
bzoj2431 HAOI2009 逆序對數列
天哪天哪天哪 我們用f i j 來表示前i個數,有j對逆序對的方案數,so考慮插入,因為i比1到i 1裡面的任何乙個數都要大,所以插入的時候後面有多少個數,就會多出多少逆序對,所以前面的符合條件的都可以轉移,f i j sigma f i 1 j k k屬於0到i 1,然而字首和神煩.include...
bzoj2431 HAOI2009 逆序對數列
dp 令b i j 表示n i,k j時的答案 則b 1 0 1 b 2 0 1 b 2 1 1 b 3 0 1 b 3 1 2 b 3 2 2 b 3 3 1 我們觀察發現 至少我是觀察 b i j b i 1 j i 1 b i 1 j 注意j i 1 0時令其為0 j i 1 i 2 2,即j...