Uva 11077 Find the Permutation

可以发现最优的方案就是一个循环节内互换。

所以一个有n个元素,c个循环节的置换的交换次数(最少)是n-c。

然后就可以递推了,把i插入到前i-1个元素构成的置换中,要么新成立一个循环,要么加入到之前的任意循环中去。

所以f[i][j]=f[i-1][j]+f[i-1][j-1]*(i-1)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define ll unsigned long long
ll f[25][25];
int n,k;

inline void init(){
	f[0][0]=1;
	for(int i=1;i<=21;i++)
	    for(int j=0;j<i;j++){
	    	f[i][j]=f[i-1][j];
	    	//i自己独立形成一个循环
	    	if(j) f[i][j]+=f[i-1][j-1]*(ll)(i-1);
	    	//i插入之前循环的任意一个位置
		}
}

int main(){
	init();

	while(scanf("%d%d",&n,&k)==2){
		if(!n&&!k) break;
		printf("%llu\n",f[n][k]);
	}

	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/8446474.html

时间: 2024-10-13 14:41:58

Uva 11077 Find the Permutation的相关文章

UVA 11077 - Find the Permutations(递推)

UVA 11077 - Find the Permutations 题目链接 题意:给定n,k求出有多少个包含元素[1-n]的序列,交换k次能得到一个[1,2,3...n]的序列 思路:递推dp[i][j]表示i个元素需要j次,那么在新加一个元素的时候,添在最后面次数不变,其余位置都是次数+1,这是可以证明的,原序列中有几个循环,需要的次数就是所有循环长度-1的和,那么对于新加一个元素,加在最后就和自己形成一个循环,次数不变,其余位置都会加入其他循环中,次数+1,因此递推式为dp(i,j)=dp

uva:11129 - An antiarithmetic permutation(分治法)

题目:11129 - An antiarithmetic permutation 题目大意:求n的反算术级数.就是排序0 ..n - 1 要求不存在长度大于2的序列.例如:5的序列排列后(0, 5, 4, 3, 1, 2) ,但是(0,1,2)是一个等差序列,同样的还有(5,4,3), (5,3,1)... 解题思路:这题需要找到排列的策略:将整个序列分成差不多等长的两个部分,使得左右两部分各自成为等差数列,这样左边的数和右边的数组合就一定不会出现等差数列.然后把这个作为子问题,递归求解.递归到

uva 11129 An antiarithmetic permutation (递归)

uva 11129 An antiarithmetic permutation A permutation of n+1 is a bijective function of the initial n+1 natural numbers: 0, 1, ... n. A permutation p is called antiarithmetic if there is no subsequence of it forming an arithmetic progression of lengt

uva 11077 置换

1 /** 2 给定一个置换,看能不能存在一个置换A^2 = B 3 思路; 循环节长度为偶数n的置换只能由循环节长度为长度2*n 的置换A*A 而变得.所以只需求出循环节,看循环节长度为偶数的个数是否为偶数个即可.. 4 训练指南 5 **/ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int maxn = 30; 11 1

UVA 11077 Find the Permutations DP

Find the Permutations Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem D Find the Permutations Input: Standard Input Output: Standard Output Sorting is one of the most used operations in real lif

Uva 11077 Find the Permutations [置换群 DP]

题意: 给定$n$和$k$,问有多少排列交换$k$次能变成升序 $n \le 21$ $uva$貌似挂掉了$vjudge$上一直排队 从某个排列到$1,2,...,n$和从$1,2,...,n$到某个排列是一样的 排列就是置换,分解循环,然后显然每个循环变成升序需要$len-1$次交换 然后有$t$个循环的置换需要$n-t$次交换 $DP$就行了$f[i][j]$表示前$i$个数有$j$个循环 其实可以发现就是第一类$stirling$数 注意:以后一定要测一遍极限会爆$long\ long$

UVA 11077 Find the Permutations 递推置换

                           Find the Permutations Sorting is one of the most used operations in real life, where Computer Science comes into act. It iswell-known that the lower bound of swap based sorting is nlog(n). It means that the best possiblesor

UVA - 11077 Find the Permutations (置换)

Sorting is one of the most usedoperations in real life, where Computer Science comes into act. It iswell-known that the lower bound of swap based sorting is nlog(n).It means that the best possible sorting algorithm will take at least W(nlog(n))swaps

UVA, 11129 An antiarithmetic permutation

题意:读入一个数n,代表从0到n-1的数列,让你输出一个数列,这个数列的子序列均不为等差数列 思路:= =参考了网上大神的代码,得到的一个规律:将等差(?)数列按奇偶位置分成两个数列,再重复这一步骤,最后得到的数列一定是非等差数列,其实就是分治法 ps:分治法:将大的问题分为无数个小问题,解决后再将得到的解合并,得到大问题的答案 例:0 1 2 3 4 5 6 7 ->(0 2 4 8)(1 3 5 7) 此刻我们得到了两个小等差数列,但此时数列已不是等差数列了 ->(0 4)(2 8)(1