poj1715Hexadecimal Numbers(数位dp)

链接

好久没写这种逐位计数的了。

先统计出总的数 ,s-n+1,倒着计算的 ,感觉倒着比较符合计算方式,总数为15*A(15,i) (1=<i<=8) 也就是1-8长度所有的排列总数

然后依次从长度1加起 加到第一个>=n的 就找到了 该字符串的长度 然后再逐位进行找下一位 首位不为0.

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 LL s;
18 LL c[30][30];
19 int a[30];
20 bool vis[30];
21 void init()
22 {
23     int i,j;
24     for(i = 1; i <= 15 ; i++)
25     {
26         c[i][0] = 1;
27         for(j = 1; j <= i; j++)
28         {
29             int k = j,g=i;
30             c[i][j] = 1;
31             while(k)
32             {
33                 c[i][j]*=g;
34                 k--;
35                 g--;
36             }
37         }
38     }
39     for(i = 1 ;i <= 8; i++)
40     {
41         s+=15*c[15][i-1];
42     }
43 }
44 int main()
45 {
46     int i,j,g,e;
47     LL n;
48     init();
49     while(cin>>n)
50     {
51         memset(vis,0,sizeof(vis));
52         n = s-n+1;
53         LL ans=0;
54         int ts = 1,len;
55         for(i = 1; i <= 8 ; i++)
56         {
57             ans+=15*c[15][i-1];
58             if(ans>=n)
59             {
60                 n = n-ans+15*c[15][i-1];
61                 len = i;
62                 break;
63             }
64         }
65         int o = 1;
66         for(i = len ; i>= 1; i--)
67         {
68             ans = 0;
69             int kk;
70             int tt;
71             if(i==len) tt = 1;
72             else tt = 0;
73             for(i==len?j = 1:j=0; j <= 15; j++)
74             {
75                 if(vis[j]) continue;
76                 ans+=c[16-o][i-1];
77                 if(ans>=n)
78                 {
79                     n = n-ans+c[16-o][i-1];
80                     a[i] = j;
81                     vis[j] = 1;
82                     o++;
83                     break;
84                 }
85                 kk = j;
86             }
87         }
88         for(j = len ; j >= 1 ; j--)
89         {
90             if(a[j]>=10)
91             printf("%c",a[j]-10+'A');
92             else
93             cout<<a[j];
94         }
95         puts("");
96     }
97     return 0;
98 }
View Code

 

 

posted @ 2014-04-03 23:21  _雨  阅读(192)  评论(0编辑  收藏  举报