uva 11077 - Find the Permutations(置换+dp)

来源:互联网 发布:手机笑声音效软件 编辑:程序博客网 时间:2024/05/18 20:35

题意:对于1~n的排列,至少交换k次才能变成1,2,3,...,n的有多少个

思路:假设每一个排列是一个置换,这个置换里有x个循环,那么这个置换想变成1,2,3,...,n至少交换n-x次,所以题意也就是有多少个排列,里面的循环<=n-k个

这个可以有dp来做,dp[i][j]表示至少交换j次,变成1,2,...,i

dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*(i-1)

dp[i-1][j]:因为这个i可以单独为一个循环

dp[i-1][j-1]*(i-1):这个i也可以加入前面的任意一个循环的任何位置

#include<bits/stdc++.h>using namespace std;typedef unsigned long long LL;const int maxn=50;LL dp[maxn][maxn];int N,K;int main(){    memset(dp,0,sizeof(dp));    dp[1][0]=1;    for(int i=2;i<=21;i++)        for(int j=0;j<=i;j++)        {            dp[i][j]=dp[i-1][j];            if(j>0)dp[i][j]+=dp[i-1][j-1]*(i-1);        }    while(scanf("%d%d",&N,&K)!=EOF,N+K)        cout<<dp[N][K]<<endl;    return 0;}





1 0
原创粉丝点击