Backward Digit Sums POJ 3187(搜索)

原题

题目连接

题目分析

这道题的难点在于搜的技巧,仔细观察会发现有些规律,就如样例一 3 1 2 4怎么得到16的,事实上是3*c(0,3)+1*c(1,3)+2*c(2,3)+4*c(3,3),具体为什么是这样可以参考杨辉三角,看每个数字贡献多少值即可.因此直接用全排列搜,搜到答案的话肯定是字典序最小的.

代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <utility>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <queue>
11 #include <map>
12 #include <set> 
13 
14 using namespace std;
15 typedef long long LL;
16 const int INF_INT=0x3f3f3f3f;
17 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 
18 
19 int c[11][11];
20 int num[10];
21 
22 void pre()
23 {
24     for(int i=0;i<=10;i++)
25     for(int j=0;j<=i;j++)
26     {
27         if(!j||j==i) c[j][i]=1;
28         else c[j][i]=c[j][i-1]+c[j-1][i-1];
29     }
30 }
31 
32 void solve(int n,int ans)
33 {
34     for(int i=1;i<=n;i++) num[i-1]=i;
35     do
36     {
37         int sum=0;
38         for(int i=0;i<n;i++) sum+=num[i]*c[i][n-1];
39         if(sum==ans) return ;
40     }while(next_permutation(num,num+n));
41 }
42 
43 int main()
44 {
45 //    freopen("black.in","r",stdin);
46 //    freopen("black.out","w",stdout);
47     pre();
48 /*    for(int i=0;i<=10;i++)
49     {
50         for(int j=0;j<=i;j++) printf("c[%d][%d]=%d ",j,i,c[j][i]);
51         cout<<endl;
52     }*/
53     int n,sum;
54     cin>>n>>sum;
55     solve(n,sum);
56     cout<<num[0];
57     for(int i=1;i<n;i++) printf(" %d",num[i]);
58     cout<<endl;
59     return 0;
60 } 

 

posted @ 2019-08-22 21:14  VBL  阅读(95)  评论(0编辑  收藏  举报