zoukankan      html  css  js  c++  java
  • 错排序问题

    题目:http://acm.hrbeu.edu.cn/index.php?act=problem&id=1008&cid=25

    写的程序就那么的耗时吗?交上去都有5分钟了,还是在Waiting。费了好大劲调,也不知道对不对,留个纪念吧。

    说一下思路:1,把第n 封信放在一个信封里,比如说是第 k 个 一共有 n - 1种方法

             2,放编号为 k 的信,有两种情况:

            (1)放在第 n 个信封里,那么,对剩余的 n - 2 个信,有 f (n - 2) 种方法。

            (2)不放在第 n 个信封里,这时,对于除第 n 封信以外剩余的 n - 1封信有 f ( n - 1) 种方法

    所以递退公式:f ( n ) = ( n - 1) * ( f ( n - 1 )  + f ( n - 2 ) ); 其中 f (1 ) = 0, f ( 2 ) = 1 ;

    其实就是一个递推题目,但是由于n最大为 1000,所以用打整数来做的

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <math.h>
     6 #define _clr(a,val) (memset(a,val,sizeof(a)))
     7 #define Max(a,b) (a) > (b) ? a : b
     8 #define Min(a,b) (a) > (b) ? b : a
     9 
    10 using namespace std;
    11 
    12 int f[1005][7000];  //  保存 n 封信时的错位方法数,f [n][0]用来记录n封信时,错位方法数的长度
    13 int tem[4];
    14 int kemp[7000];
    15 void ca()
    16 {
    17     int i,j,k;
    18     _clr(f,0);
    19     f[1][0] = f[2][0] = 1;
    20     f[1][1] = 0;
    21     f[2][1] = 1;
    22     int len;
    23     for(i = 3; i <= 1000; i++)
    24     {
    25         len = Max(f[i - 1][0],f[i - 2][0]);
    26         for(j = 1; j <= len; j++)
    27         {
    28             f[i][j] += (f[i - 1][j] + f[i - 2][j]);  // 首先计算  f ( n - 1)  + f ( n - 2)
    29             if(f[i][j] > 9)
    30             {
    31                 f[i][j + 1] += (f[i][j] / 10);
    32                 f[i][j] %= 10;
    33             }
    34         }
    35         if(f[i][len + 1]) f[i][0] = len + 1;
    36         else f[i][0] = len;
    37         int kem = i - 1;
    38         int num = 0;
    39         while(kem)
    40         {
    41             tem[++num] = kem % 10;
    42             kem /= 10;
    43         }
    44         _clr(kemp,0);
    45         for(j = 1; j <= num; j++)
    46         {
    47             for(k = 1; k <= f[i][0]; k++)
    48             {
    49                 kemp[j + k - 1] += (f[i][k] * tem[j]);  // 乘以 ( n - 1)
    50                 if(kemp[j + k - 1] > 9)
    51                 {
    52                     kemp[j + k] += kemp[j + k - 1] / 10;
    53                     kemp[j + k - 1] %= 10;
    54                 }
    55             }
    56         }
    57         if(kemp[num + f[i][0]]) f[i][0] = (num + f[i][0]);
    58         else f[i][0] = (num + f[i][0] - 1);
    59         for(j = 1; j <= f[i][0]; j++)
    60         {
    61             f[i][j] = kemp[j];
    62         }
    63     }
    64 }
    65 int main()
    66 {
    67     int i;
    68     memset(f,0,sizeof(f));
    69     ca();
    70     int n;
    71     //freopen("data.txt","r",stdin);
    72     //freopen("data.out","w",stdout);
    73     while(cin>>n)
    74     {
    75         i = f[n][0];
    76         //cout<<f[n][0];
    77         if(f[n][i] < 0) i--;
    78         for(; i >= 1; i--)
    79         printf("%d",f[n][i]);
    80         cout<<endl;
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    [Leetcode 56] 55 Jump Game
    [Leetcode 57] 61 Rotate List
    [Leetcode 61] 73 Set Matrix Zeros
    [Leetcode 62] 74 Search a 2D Matrix
    [Leetcode 64] 78 Subsets
    [Leetcode 63] 77 Combinations
    [Leetcode 58] 63 Unique Path II
    python学习笔记第1章节 基础知识
    python学习笔记第2章节 分支,循环,还有条件
    visual studio 2008 试用版评估期已结束的解决方法(转载)
  • 原文地址:https://www.cnblogs.com/fxh19911107/p/2682442.html
Copyright © 2011-2022 走看看