• 递推置换,交换次数最少得到升序序列


    UVA11077

    题意: 

    给定一个1~n的排序,可以通过一系列的交换变成1,2,…,n, 给定n和k,统计有多少个排列至少需要交换k次才能变成有序的序列。

    题解: 

    每个长度为n循环需要交换n-1次才能将交换到对应的位置,例如1->2,2->4,4->1,(1,2,4)位置上对应值为(2,4,1) 相当于一个长度为3的环逆时针旋转了1格,要变换回来,需要跟原位置交换,因为成环,所以共n-1次     那么对于序列P,有x个循环节,长度为n,就需要交换n-x次     对于f[i][j],表示交换j次能变为1~i的序列的种数     我们找到递推式:f[i][j]=f[i-1][j]+f[i-1][j-1]*(i-1),边界是f[1][0]=1,其余为0     解释:新增的i,如果与自己构成循环,那么循环数和长度都加一,交换数不变,所以是f[i-1][j]         新增的i,如果参加到其他环中,每个数后一种,共i-1种,循环数不变,长度加一,所以是f[i-1][j-1]*(i-1)     例如1->2,2->3,3->1,{2,3,1};将4添加到1后就是1->4,4->2,2->3,3->1,序列为{4,3,1,2};其他同上

     1 #include<bits/stdc++.h>
     2 #define mp make_pair
     3 #define pb push_back
     4 #define first fi
     5 #define second se
     6 #define pw(x) (1ll << (x))
     7 #define sz(x) ((int)(x).size())
     8 #define all(x) (x).begin(),(x).end()
     9 #define rep(i,l,r) for(int i=(l);i<(r);i++)
    10 #define per(i,r,l) for(int i=(r);i>=(l);i--)
    11 #define FOR(i,l,r) for(int i=(l);i<=(r);i++)
    12 #define eps 1e-9
    13 #define PIE acos(-1)
    14 #define cl(a,b) memset(a,b,sizeof(a))
    15 #define fastio ios::sync_with_stdio(false);cin.tie(0);
    16 #define lson l , mid , ls
    17 #define rson mid + 1 , r , rs
    18 #define ls (rt<<1)
    19 #define rs (ls|1)
    20 #define INF 0x3f3f3f3f
    21 #define LINF 0x3f3f3f3f3f3f3f3f
    22 #define freopen freopen("in.txt","r",stdin);
    23 #define cfin ifstream cin("in.txt");
    24 #define lowbit(x) (x&(-x))
    25 #define sqr(a) a*a
    26 #define ll long long
    27 #define ull unsigned long long
    28 #define vi vector<int>
    29 #define pii pair<int, int>
    30 #define dd(x) cout << #x << " = " << (x) << ", "
    31 #define de(x) cout << #x << " = " << (x) << "
    "
    32 #define endl "
    "
    33 using namespace std;
    34 //**********************************
    35 ull dp[25][25];//dp[i][j]表示前i个数至少用k次交换的排列数 
    36 int n,k;
    37 //**********************************
    38 void Init()
    39 {
    40     FOR(i,1,21){
    41         dp[i][0]=1;
    42         rep(j,1,i){
    43             dp[i][j]=dp[i-1][j-1]*(i-1)+dp[i-1][j];;
    44         }
    45     }
    46 }
    47 //**********************************
    48 int main()
    49 
    50 {
    51     Init();
    52     while(cin>>n>>k,n+k){
    53         cout<<dp[n][k]<<endl;
    54     }
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    U盘安装WIN10专业版
    jquery template模版引擎
    MySQL大数据量快速分页实现(转载)
    MySQL for Windows 解压缩版安装 和 多实例安装
    macbook 重装win7
    MySQL for Visual Studio Version
    VS2010中没有ado.net entity data model实体数据模型这一选项-解决办法
    修改server 2008远程桌面端口
    懒加载
    html-css 常用
  • 原文地址:https://www.cnblogs.com/klaycf/p/9682046.html
Copyright © 2020-2023  润新知