sicily 解题报告: 1280 Permutation

原创 2007年09月23日 23:44:00

Permutation


Total Submit : 120    Accepted Submit : 47

Problem

Given a permutation of n elements (1, 2, ..., n): A = (a1, a2, ..., an). We define a sequence P(A)=(p1, p2, , p(n-1)) where pi = 0 if A(i) > A(i+1) and pi = 1 if A(i) < A(i+1). Given a permutation B, find the number of all permutations C where P(C)=P(B) including the permutation B itself. 


Input

The input text file contains several tests, each on a separate line. The first number in the test is n followed by n numbers representing the permutation all of them separated by a single space. The last line in the input contatins only 0 and should not be processed. 

Output

The output should be written on the standard output. For each line in the input (excluding the last one, 0) you should write the result i.e. the number of the permutations having the same value for P(A) when given the permutation A. 


Sample input

2 1 2
4 1 3 2 4
0

Sample output

1
5

Problem Source

ZSUACM Team Member

================
========邪恶的分割线=========================
http://p.blog.csdn.net/images/p_blog_csdn_net/rappy/334350/o_1.jpg
题目的要求是按照升降序列来构造排列,可用构造一段三角波来描述这个过程。
三角波上的离散点的相对位置只表示相对大小,在还没添加所有的点之前,各个点并没有确定实际值。
对于当前点 Vi (i 从 0 开始),假设已经有 a 个点比它大,有 b 个点比它小,a + b = i 。(对于点 V0 , a0 = 0 , b0 = 0 。)
如图 1 所示 ,小三角标示当前点,(a, b) = (1, 3) 表示有 1 个点高于其,有 3 个点低于其。注意任意两点的高度都不相等
那么要添加下一个点时, 根据点之间的相对位置来划分,
(1) 上升有 a + 1 种位置,新点的 a' = 0 .. a , b' = a+b+1 .. b+1 。如图 2 所示,每个小三角标示的点都可以作为添加的点。
(2) 下降有 b + 1 种位置,新点的 a' = a+b+1 .. a+1 ,b' = 0 .. b 。如图 3 所示。

因为 (
ai , bi ) 可能会有重复的,所以只要记录其数目即可。
因为 ai + bi = i ,所以只要记录
bi 即可。
因此使用一个二维数组 cnt [ ] [ ],行标 i 表示第 i 个点,列标 j 表示低于第 i 个点的点的数目,cnt [ i ] [ j ] 表示可行的情况数目。

例如升降序列是 “降升降” (n = 4) ,那么构造所有的三角波,构造完成后根据点的高度来给它赋值 1 .. n 。
http://p.blog.csdn.net/images/p_blog_csdn_net/rappy/334350/o_2.jpg
生成的 5 个排列是 4132 , 4231,2143, 3142, 3241 。

过程中产生的 (a, b),如对于 V3 , (3, 0) 出现两次,则 cnt [3] [0] = 2。
点 (a, b)
0    (0, 0)
1    (1, 0)
2    (0, 2),(1, 1)
3    (3, 0),(2, 1),(1, 2)   (3, 0),(3, 1)
和上面的图顺序有点不一样,当时没在图上标示好,将就点吧 o(∩_∩)o...

如果上升,那么 cnt [i - 1] [j] 对应的位置都能够产生 cnt [i] [j+1..i] 对应的某个位置。
如果下降,那么 cnt [i - 1] [j] 对应的位置都能够产生 cnt [i] [0..j] 对应的某个位置。
代码如下:
(递推法分析,然后动态规划实现,时间复杂度是 O (n3) 的)

#include <cstdio>
#include 
<memory.h>
using namespace std;

const int N = 100;
long long cnt [N] [N];
int seq [N];
int n;

void f ()
{
    memset (cnt, 
0sizeof (cnt));
    cnt [
0] [0= 1;
    
int i, j, k;
    
for (i = 0; i < n; i ++)
        
{
        scanf (
"%d"&seq [i]);
        }

    
for (i = n - 1; i; i --)
        
{
        seq [i] 
= (seq [i] > seq [i - 1? 1 : 0);
        }

    
for (i = 1; i < n; i ++)
        
{
        
for (j = 0; j <= i; j ++)
            
{
            
if (seq [i])
                
{
                
// 如果上升则 cnt [i - 1] [j] 对应的位置都能够产生 cnt [i] [j+1..i] 对应的某个位置
                for (k = j + 1; k <= i; k ++)
                    
{
                    cnt [i] [k] 
+= cnt [i - 1] [j];
                    }

                }
 else    {
                    
// 如果下降则 cnt [i - 1] [j] 对应的位置都能够产生 cnt [i] [0..j] 对应的某个位置
                    for (k = 0; k <= j; k ++)
                        
{
                        cnt [i] [k] 
+= cnt [i - 1] [j];
                        }

                    }

            }

        }

    
long long sum = 0;
    
for (i = 0;  i < n; i ++)
        
{
        sum 
+= cnt [n - 1] [i];
        }

    printf (
"%lld ", sum);
}


int main ()
{
    
while (scanf ("%d"&n), n)
        
{
        f ();
        }

    
return 0;
}


提交结果:

Run ID      User Name      Problem      Language      Status      Run Time      Run Memory      Submit Time
86144       rappizit     1280     C++     Accepted     0 sec     332 KB     2007-09-23 23:09:49

PS:这次报告写得不怎么样。。表达能力不高,见笑了。。
今天晚上吃了月饼,呵呵。。

Sicily 1687 Permutation

动态规划,对于n个数字,k个
  • mayer314
  • mayer314
  • 2014年11月21日 22:48
  • 219

sicily 1687. Permutation

http://soj.sysu.edu.cn/show_problem.php?pid=1687 因为每次加进去的数是最大的,所以只有两种情况,一种就是加入之后个数不变,另一种就是+1 例子: 1...
  • w316497555
  • w316497555
  • 2015年06月12日 21:42
  • 406

Sicily 1280. Permutation

1280. Permutation Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description ...
  • u012925008
  • u012925008
  • 2015年03月24日 18:59
  • 482

sicily--1775. Simple Sort

1.由于最近一直想学号优先级队列,所以还是用了优先级队列 2.由一个优先级对列 seq 来储存最后输入的“优先级”信息,并按“优先级”由小到大排好序; 再创建一个优先级队列Q 按照 seq 排好的顺...
  • chenhq1991
  • chenhq1991
  • 2012年08月15日 23:13
  • 1192

sicily--1486. 统计数字

绝对不难但又绝对坑人用cin、cout 会超时每个测试数据的输出之间还要空一行,最后一个测试数据不能有空行用map 可以解决这个题目的排序问题, map内部使用的红黑树,会自动排序 //map ...
  • chenhq1991
  • chenhq1991
  • 2012年07月18日 13:32
  • 1504

排列组合(permutation)系列解题报告

本文讲解4道关于permutation的题目。 1. Permutation:输出permutation——基础递归 2. Permutation Sequence: 输出第k个permutatio...
  • abcjennifer
  • abcjennifer
  • 2014年10月18日 18:46
  • 9240

sicily题目分类

sicily题目分类 1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. ...
  • u010858667
  • u010858667
  • 2013年09月05日 11:52
  • 2165

SOJ题型分类

sicily 1198 贪心,8个串排出最小字典序,8!枚举 sicily 1029 递推 简单 sicily 1028 梵塔问题 -> 分治,归纳 -> 有意思但要留意其数据规模较大 sicily ...
  • chengyangyy
  • chengyangyy
  • 2013年08月25日 01:05
  • 2501

Permutation递归解法

permutation类型题的解法
  • a6219221
  • a6219221
  • 2016年09月07日 03:21
  • 521

Sicily 1154. Easy sort

就写一个排序算法~ 懒人可以直接使用里面的sort~ 强人直接写一个快速排序或堆排序或基数排序 鄙人写了一个插入排序....... // Problem#: 1154 // Author#: 3254...
  • chhj0103121429
  • chhj0103121429
  • 2014年12月21日 11:53
  • 538
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:sicily 解题报告: 1280 Permutation
举报原因:
原因补充:

(最多只允许输入30个字)