UVA 11077 Find the Permutations(置换+dp)

来源:互联网 发布:企业域名邮箱给我一个 编辑:程序博客网 时间:2024/06/11 11:04

题意:求将n个数的某个排列交换到顺序时的最小次数为k的排列个数。

思路:将每个排列看成一个置换,那么对于置换的每个循环节,需要交换循环节长度-1次,两个循环节之间不需要交换。那么用dp[i][j]表示1~i的数需要交换次数为j的排列数,要么i自己成为一个循环,这不提供额外的交换次数,要么与前面某个数交换,即加入某个循环,这个交换次数需要+1。可以得到dp[i][j]=dp[i-1][j-1]*(i-1)+dp[i-1][j]。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef unsigned long long ll;const int maxn=22;ll dp[22][22];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    memset(dp,0,sizeof(dp));    dp[0][0]=1;    for(int i=1;i<maxn;++i)    {        dp[i][0]=1;        for(int j=1;j<maxn;++j)            dp[i][j]=dp[i-1][j-1]*(i-1)+dp[i-1][j];    }    int n,k;    while(cin>>n>>k)    {        if(n==0&&k==0) break;        cout<<dp[n][k]<<endl;    }    return 0;}


0 0
原创粉丝点击