UVA 331 交换的方案数

题意:交换一个数组的相邻两个元素可以达到对数组排序的功能,类似于冒泡排序,但交换的方案可能不止一种。比如说数组A【3】为3,2,1,要想排为1,2,3,可以先交换位置1和2的元素(数组变为2,3,1),然后交换位置2和3的元素(变为2,1,3),最后交换位置1和2的(变为1,2,3),此为方案一,具体可以用1,2,1(数字即每次交换的第一个数的位置)来描述。当然还可以先交换位置2和3(312),然后交换位置1和2(132)最后交换位置2和3(123),如上的描述方法便是2,1,2,此为方案二。当然这样的方案是无穷多的,比如1,1,2,1,2同样可以实现排序,但这种情况下前两次交换是在做无用功,不是移动次数最小的方案。此题要求出移动次数最少的方案有多少个,如例子中的情况就只有2种方案。

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cctype>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <map>
10 #include <set>
11 #include <algorithm>
12 #include <iostream>
13 using namespace std;
14 typedef long long ll;
15 const int NO = 10000 + 10;
16 int a[NO];
17 int n, ans;
18
19 inline bool judge()
20 {
21     for( int i = 1; i < n; ++i )
22         if( a[i] > a[i+1] )
23             return false;
24     return true;
25 }
26
27 int Swap( int i, int j )
28 {
29     int t = a[i];
30     a[i] = a[j];
31     a[j] = t;
32 }
33
34 void dfs()
35 {
36     if( judge() )
37     {
38         ++ans;
39         return;
40     }
41     for( int i = 1; i < n; ++i )
42         if( a[i]  > a[i+1] )
43         {
44             Swap( i, i+1 );
45             dfs();
46             Swap( i, i+1 );
47         }
48 }
49
50 int main()
51 {
52     int T = 0;
53     while( ~scanf( "%d", &n ) && n )
54     {
55         for( int i = 1; i <= n; ++i )
56             scanf( "%d", &a[i] );
57         ans = 0;
58         if( !judge() )
59             dfs();
60         printf( "There are %d swap maps for input data set %d.\n", ans, ++T );
61     }
62     return 0;
63 }

时间: 2024-10-08 20:04:32

UVA 331 交换的方案数的相关文章

UVa 331 交换的方案数 (回溯法,启发)

题意:只能交换相邻的数.要把一个数组这样交换以形成升序.问最少交换次数的不同交换顺序有多少种. 思路:还是没想到,看到别人题解中一句话,茅塞顿开:每次从头选两个需要交换的位置进行交换.只有降序才需要交换,而且可以看到每次降序的调换都是有意义的.这样每次从头找一个需要交换的位置,就是不同的方案.当某次从头扫描到尾没有需要交换的位置时,则已经排好序,就是交换次数,用一个flag变量标志. 0.022s,还好,就没有剪枝优化.这题还是可以剪枝的. 这题对回溯法的应用和思路很有启发意义~ Code: #

UVa 11137 (完全背包方案数) Ingenuous Cubrency

题意:用13.23……k3这些数加起来组成n,输出总方案数 d(i, j)表示前i个数构成j的方案数则有 d(i, j) = d(i-1, j) + d(i, j - i3) 可以像01背包那样用滚动数组来实现 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 10; 8

uva 331 Mapping the Swaps (回溯)

uva 331 Mapping the Swaps Sorting an array can be done by swapping certain pairs of adjacent entries in the array. This is the fundamental technique used in the well-known bubble sort. If we list the identities of the pairs to be swapped, in the sequ

UVa 991 Safe Salutations 卡特兰数

题目来源:UVa 991 Safe Salutations 题意:圆上2*n个点均匀分布 两两相连 求不相交的方案数 思路:卡特兰数的应用 以下总结转自某大牛 /* 最典型的四类应用:(实质上却都一样,无非是递归等式的应用,就看你能不能分解问题写出递归式了) 1.括号化问题. 矩阵链乘: P=a1×a2×a3×--×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种) 2.出栈次序问题. 一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的

Party at Hali-Bula(树形DP+判断方案数是否唯一)

Party at Hali-Bula UVA - 1220 题意: 公司里有n(n<=200)个人形成一个树状结构, 要求尽量选多的人,但不能同时选择一个人和他的直属上司,文最多能选多少人,以及是否方案唯一. 1 //dp[x][0]表示不选X节点能达到的最大人数,dp[x][1]表示选x节点的最大人数 2 //f数组含义和dp基本一致,f[x][0]表示如果不选x节点是否方案数唯一 f[x][1]表示如果选x节点方案数是否唯一 3 //如果f数组为1表示方案数不唯一 4 //对于一个根节点,如

洛谷P1108 低价购买[DP | LIS方案数]

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期 1 2

CF GYM100548 (相邻格子颜色不同的方案数 2014西安区域赛F题 容斥原理)

n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数. integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m). m种颜色取k种 C(m, k) 这个可以放最后乘 那么问题就变成只用k种颜色第一个格子有k种涂法 第二个有k-1种 第三个也是k-1种 一共就是k*(k-1)^(n-1) 这种算法仅保证了相邻颜色不同,总颜色数不超过k种,并没有保证恰好出现k种颜色 也就是多算了恰好出现2种 恰好出现3种...

NOIP2012pj摆花[DP 多重背包方案数]

题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列. 试编程计算,一共有多少种不同的摆花方案. 输入输出格式 输入格式: 第一行包含两个正整数n和m,中间用一个空格隔开. 第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1.a2.……an. 输出格式: 输出只有一行,一个整数

hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)

n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就 等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数 Sample Input4 4 // n m0 10 21 32 32 //T0 3 2