51nod 1250 排列與交換

2021-08-02 20:15:20 字數 1365 閱讀 9358

對a進行好恰好k次相鄰交換,能得到多少個不同的序列 (s1)?

對a進行最多k次交換,你能得到多少個不同的序列 (s2)?

一次相鄰交換是指交換陣列a中兩個相鄰位置的元素,即:交換a[i]和a[i+1]或者a[i]和a[i-1]。

一次交換是指交換陣列a中的任意兩個位置不同的元素,即:交換a[i]和a[j],1 <= i, j <= n, i != j。

給出陣列a的長度n,以及次數k,求s1和s2。由於結果很大,輸出mod 1000000007的結果。

例如:原始陣列: [1, 2, 3]

經過兩次相鄰交換:

我們得到 [1, 2, 3], [2, 3, 1], [3, 1, 2] ==> s1 = 3

經過最多兩次交換:

1) 0次交換後: [1, 2, 3]

2) 1次交換後: [2, 1, 3], [3, 2, 1], [1, 3, 2].

3) 兩次交換後: [1, 2, 3], [2, 3, 1], [3, 1, 2] ==> s2 = 6

input

輸入2個數n, k,中間用空格分隔,(1 <= n, k <= 3000)

output

輸出2個數s1, s2 mod 1000000007的結果,中間用空格分隔。

input示例

3 2

output示例

3 6第一問逆序對dp。

第二問普通dp。

//51nod 1250 排列與交換

#include

#define ll long long

#define m(a) memset(a,0,sizeof a)

#define fo(i,j,k) for(i=j;i<=k;i++)

using namespace std;

const int mxn=3005;

const int mod=1e9+7;

int n,k,ans;

int dp[mxn][mxn];

int main()

}fo(i,0,k) if((k-i)%2==0) ans=(ans+dp[n][i])%mod;

printf("%d ",ans);

ans=0,m(dp);

fo(i,0,n) dp[i][0]=1;

fo(i,1,n) fo(j,1,k)

dp[i][j]=(dp[i-1][j]+(ll)(i-1)*dp[i-1][j-1]%mod)%mod;

fo(i,0,k) ans=(ans+dp[n][i])%mod;

printf("%d\n",ans);

return

0;}

51nod 1250 排列與交換

題目大意 你有乙個初始為 1 到 n的順序陣列 問題一 恰好進行 k 次相鄰交換,最後有多少不同的排列 問題二 進行不多於 k次交換 不一定相鄰 最後有多少種不同的排列 n k 3000 思路 這道題沒有什麼新意,其主要思路就是將恰好變為最少,即乙個排列我們要用最少的操作次數得到。對於第一問,考慮乙...

51Nod1250 排列與交換

乙個陣列a 1,2,3,n 對a進行好恰好k次相鄰交換,能得到多少個不同的序列 s1 對a進行最多k次交換,你能得到多少個不同的序列 s2 一次相鄰交換是指交換陣列a中兩個相鄰位置的元素,即 交換a i 和a i 1 或者a i 和a i 1 一次交換是指交換陣列a中的任意兩個位置不同的元素,即 交...

51nod 1574 排列轉換

現在有兩個長度為n的排列p和s。要求通過交換使得p變成s。交換 pi 和 pj 的代價是 i j 要求使用最少的代價讓p變成s。單組測試資料。第一行有乙個整數n 1 n 200000 表示排列的長度。第二行有n個範圍是1到n的整數,表示排列p。每個整數只出現一次。第三行有n個範圍是1到n的整數,表示...