對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的整數,表示...