日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷 P2513 [HAOI2009]逆序对数列

發布時間:2024/4/17 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷 P2513 [HAOI2009]逆序对数列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

對于一個數列{ai},如果有i<j且ai>aj,那么我們稱ai與aj為一對逆序對數。若對于任意一個由1~n自然數組成的數列,可以很容易求出有多少個逆序對數。那么逆序對數為k的這樣自然數數列到底有多少個?

輸入輸出格式

輸入格式:

?

第一行為兩個整數n,k。

?

輸出格式:

?

寫入一個整數,表示符合條件的數列個數,由于這個數可能很大,你只需輸出該數對10000求余數后的結果。

?

輸入輸出樣例

輸入樣例#1:
4 1 輸出樣例#1:
3

說明

樣例說明:

下列3個數列逆序對數都為1;分別是1 2 4 3 ;1 3 2 4 ;2 1 3 4;

測試數據范圍

30%的數據 n<=12

100%的數據 n<=1000,k<=1000

?

一道簡單題,但我覺得可以做到更大的數據,比方說加兩個0

從小到大考慮每一位,先考慮1,如果1位于i這個位置,那1與1~i-1這些位置的每一個數都會產生一個逆序對,與i+1~n這些位置的數都不會產生逆序對,至于具體每個數字是什么對于1的貢獻沒有影響

然后從排列里把1去掉,變成一個2~n的排列,這個排列與1~n-1的排列是等價的,于是問題轉化成了一個較小的問題

然后可以dp

dp[i][j]表示1~i的排列,要有j個逆序對的方法數,枚舉當前位置產生的逆序對來轉移,這個東西本來是nk^2的,但是發現一個位置轉移的時候是連續的一段,用前綴和優化去掉一個k即可

其實這個問題等價于有n個帶編號的盒子排成一列,一共放k個球,標號為i的盒子里不能放超過i-1個球,求方法總數,這應該是有更好的做法的

UPD1:這個東西的生成函數是 $ (1)(1+x)(1+x+x^2)(1+x+x^2+x^3)...(1+x+x^2+...+x^{n-1}) $ 即 $ \prod_{p=1}^{n}\sum_{q=0}^{p-1}x^q?$ ,這個形式過于美妙讓人很難不認為它有一個優美的通解

1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 10000 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define mp make_pair 21 #define set0(n) memset(n,0,sizeof(n)) 22 #define ll long long 23 #define ull unsigned long long 24 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 25 #define max(a,b) (a>b?a:b) 26 #define min(a,b) (a<b?a:b) 27 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 28 #define TO(j) printf(#j": %d\n",j); 29 //#define OJ 30 using namespace std; 31 const int MAXINT = 100010; 32 const int MAXNODE = 100010; 33 const int MAXEDGE = 2*MAXNODE; 34 char BUF,*buf; 35 int read(){ 36 char c=getchar();int f=1,x=0; 37 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 38 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 39 return f*x; 40 } 41 char get_ch(){ 42 char c=getchar(); 43 while(!isalpha(c)) c=getchar(); 44 return c; 45 } 46 //------------------- Head Files ----------------------// 47 48 int n,k; 49 int dp[10010],sum[10010]; 50 void get_input(); 51 void work(); 52 int main() { 53 get_input(); 54 work(); 55 return 0; 56 } 57 void work(){ 58 fill(sum,sum+k+1,1); 59 for(int i=2;i<=n;i++){ //box no i,can take 0~i-1 60 rep0(j,k+1){ 61 dp[j] = (j-i+1>0?sum[j]-sum[j-i]:sum[j]); 62 } 63 sum[0]=dp[0]; 64 rep1(j,k){ 65 sum[j]=(sum[j-1]+dp[j])%MOD; 66 } 67 } 68 printf("%d\n",(dp[k]+MOD)%MOD); 69 } 70 void get_input(){ 71 n=read();k=read(); 72 }

?

轉載于:https://www.cnblogs.com/LoveYayoi/p/6921138.html

總結

以上是生活随笔為你收集整理的洛谷 P2513 [HAOI2009]逆序对数列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。