错排序问题
题目: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 }