51nod 1020 逆序排列 (DP_好題)
第1行:一個數T,表示後面用作輸入測試的數的數量。(1 <= T <= 10000) 第2 - T + 1行:每行2個數n,k。中間用空格分隔。(2 <= n <= 1000, 0 <= k <= 20000)Output
共T行,對應逆序排列的數量 Mod (10^9 + 7)Input示例
1 4 3Output示例
6
設f(n,k)表示n個數的排列中逆序數個數為k的排列數。
最大的數n可能會排在第n-i位,從而產生i個與n有關的逆序對,去掉n之後,剩下的n-1個數的排列有k-i個逆序對。所以,f(n,k)=求和(f(n-1,k-i))(0<=i<n)。 同理有f(n,k-1)=求和(f(n-1,k-1-i))(0<=i<n)。 兩式相減,可得f(n,k)-f(n,k-1)=f(n-1,k)-f(n-1,k-n)。 遞推公式為f(n,k)=f(n,k-1)+f(n-1,k)-f(n-1,k-n)。 然後動態規劃可得。#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; int f[1111][22222]; const int mod=1e9+7; void init() { int i,j; for(i=1;i<=1000;i++) f[i][0]=1; for(i=2;i<=1000;i++) { for(j=1;j<=i*(i-1)/2&&j<=20000;j++){ f[i][j]=(f[i][j-1]+f[i-1][j])%mod; if(j-i>=0) f[i][j]=((f[i][j]-f[i-1][j-i])%mod+mod)%mod; } } } int main() { int t,i,j,n,m; init(); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); printf("%d\n",f[n][m]); } return 0; }
相關推薦
51nod 1020 逆序排列 (DP_好題)
在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。 如2 4 3 1中,2 1,4 3,4 1,3
51nod 1020 逆序排列【Dp+思維遞推優化】好題!好題!好題!
基準時間限制:2 秒 空間限制:131072 KB 分值: 80 難度:5級演算法題 在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。 如2 4 3 1中,2
51nod 1020 逆序排列
quest 技術分享 logs class tps return mod div tput 1020 逆序排列 基準時間限制:2 秒 空間限制:131072 KB 分值: 80 難度:5級算法題 收藏 關註 在一個排列中,如果一對數的前後位置與大小順序相
51nod 1020 逆序排列 遞推DP
公式 problem 一個 def 分別是 nbsp 最大 nco 例如 1020 逆序排列 基準時間限制:2 秒 空間限制:131072 KB 分值: 80 難度:5級算法題 收藏 關註 在一個排列中,如果一對數的前後位置與大
51Nod 1020 - 逆序排列(DP)
題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 【題目描述】 在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排
51nod 1020 逆序排列 (DP)
基準時間限制:2 秒 空間限制:131072 KB 在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序數是4。 1
51nod 1020 逆序排列(dp)
想破腦袋也想不到。。。。 先定義狀態,dp[i][j]表示i個數字的全排列中逆序數為j的序列的個數 剛開始做的時候,拿筆畫了一會,憑著感覺蒙了個狀態轉移方程:dp[i][j]=dp[i-1][j]+
51nod 1020逆序排列
題解: 這題肯定是DP題。定義f[i][j]表示前i個數,產生j組逆序對的排列數量。那麼顯然可以想到n^3的做法,就是列舉當前第i個數放在哪裡。但是這樣是會超時的。但是我們可以稍加推導,最後得出f[i][j]=f[i][j-1]+f[i-1][j]-f
51nod 1020 逆序排列【DP】
Description 在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序數是4。 1-n的全排列中
51nod 1270 陣列的最大代價 (DP_好題)
陣列A包含N個元素A1, A2......AN。陣列B包含N個元素B1, B2......BN。並且陣列A中的每一個元素Ai,都滿足1 <= Ai <= Bi。陣列A的代價定義如下
10.14 將n個數按輸入輸出順序的逆序排列,用函數實現
bdn r+ mvt b2c odr ack thp zip evb 將n個數按輸入輸出順序的逆序排列,用函數實現。 #include <stdio.h> int main(){ int n,i; void reverse(int * num
51nod1020 逆序排列
amp 直接 技術分享 span ring queue std iostream scanf t<=10000個問,每次問n<=1000的全排列中逆序數對為k<=10000個的有多少,mod 1e9+7。 直接dp,$f(i,j)$--i的全排列中逆序數對
[USACO17FEB] Why Did the Cow Cross the Road I P (樹狀數組求逆序對 易錯題)
-h 特殊性 另一個 %d .org class data 操作 efi 題目大意:給你兩個序列,可以序列進行若幹次旋轉操作(兩個都可以轉),對兩個序列相同權值的地方連邊,求最少的交點數 記錄某個值在第一個序列的位置,再記錄第二個序列中某個值 在第一個序列出現的位置 ,求逆
將n個數按輸入時順序的逆序排列,用函式實現(指標)
#include <stdio.h> void reverse(int a[],int n) { int *p; for(p=a+n-1;p>=a;p--) &nb
一段讀取檔案,逆序排列的lua指令碼
local method = ngx.var.request_method; local headers = ngx.req.get_headers(); local uri_args = ngx.r
資料庫SQL實戰 —— 查詢employees表所有emp_no為奇數,且last_name不為Mary的員工資訊,並按照hire_date逆序排列
時間限制:1秒 空間限制:32768K 題目描述 查詢employees表所有emp_no為奇數,且last_name不為Mary的員工資訊,並按照hire_date逆序排列 CREATE TABL
劍指offer——字串的排列(好題,擴充套件題也很好,全排列的演算法)
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述: 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字
藍橋杯 演算法提高 ADV-103 逆序排列 迴圈語句 陣列操作
演算法提高 逆序排列 時間限制:1.0s 記憶體限制:512.0MB 問題描述 編寫一個程式,讀入一組整數(不超過20個),並把它們儲存在一個整型陣列中。當用戶輸入0時,表示輸入結束。然後程式將把這個陣列中的值按逆序重新存放,並打印出來。例如:假設使用者輸入了一組資料:7 19
JAVA陣列學習之一:對一維陣列進行逆序排列
Java中的陣列必須先初始化,然後才能使用。所謂初始化,就是為陣列中的元素分配記憶體空間,併為元素賦值。 陣列的初始化方式: 動態初始化:初始化時只指定陣列長度,由系統為陣列分配初始值。 靜態初始化:
9.28機試 定義兩個陣列,首先把兩個數組合併成一個新陣列,然後把新陣列中的所有元素逆序排列
public class Demo7 { public static void main(String[] args) { int[]array1 = new int[]{10,20,30};