【穷竭】POJ3187-Backward Digit Sums

【思路】

利用杨辉三角形,每一个数字被加的次数等于它在杨辉三角形中对应的那个数字。注意这道题的意思是,最底层是N的全排序,而不是指1..10都可以。生成杨辉三角形的时候第一次我用了二重循环模拟生成,后来学习到,杨辉三角形中,第n行第k个数字为Cnk。不过在第二个程序中我的杨辉三角形没有预处理,导致了很多时间的浪费。用了深搜和STL两种方法。深搜因为能够剪枝所以明显要比Next_permuation快。

 1 /*232K    0MS*/ 
 2 /*模拟+深搜*/
 3 #include<iostream>
 4 #include<cstdio>
 5 using namespace std;
 6 const int MAXN=10+5;
 7 int n,sum;
 8 int a[MAXN][MAXN];
 9 int ans[MAXN];
10 int vis[MAXN];
11 int f;
12 
13 void gettri()
14 {
15     for (int i=0;i<n;i++)
16     {
17         a[i][0]=1;
18         a[i][i]=1;
19     }
20     for (int i=2;i<n;i++)
21         for (int j=1;j<i;j++)
22             a[i][j]=a[i-1][j-1]+a[i-1][j];
23 }
24 
25 void print()
26 {
27     for (int i=0;i<n;i++) cout<<ans[i]<<' ';
28     cout<<endl;
29 }
30 
31 void getnum(int step,int nowsum)
32 {
33     if (step==n)
34     {
35         if (nowsum==sum)
36         {
37             f=1;
38             printf(); 
39         } 
40         return;
41     }
42     if (f||nowsum>sum) return;
43     for (int i=1;i<=n;i++)
44     {
45         if (vis[i]==1) continue;
46         vis[i]=1;
47         ans[step]=i;
48         getnum(step+1,nowsum+i*a[n-1][step]);
49         vis[i]=0;
50     }
51 }
52 
53 int main()
54 {
55     scanf("%d%d",&n,&sum);
56     gettri();
57     
58     memset(vis,0,sizeof(vis));
59     f=0;
60     getnum(0,0);
61     return 0;
62 }
 1 /*232K    469MS*/
 2 /*组合+STL*/ 
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 const int MAXN=10+3;
 9 int n,sum;
10 int ans[MAXN];
11 
12 int c(int n,int k)
13 {
14     int cresult=1;
15     for (int i=0;i<k;i++) cresult=cresult*(n-i)/(i+1);
16     //这里不能写成cresult=cresult*(n-i)/(k-i),因为如果从大到小可能无法整除,精确度会导致错误 
17     return cresult;
18 }
19 
20 int main()
21 {
22     scanf("%d%d",&n,&sum);
23     for (int i=0;i<n;i++) ans[i]=i+1;
24     do
25     {
26         int result=0;
27         for (int i=0;i<n;i++) result+=ans[i]*c(n-1,i);
28         if (result==sum)
29         {
30             for (int i=0;i<n;i++) cout<<ans[i]<<' ';
31             cout<<endl;
32             break;
33         }
34     }while (next_permutation(ans,ans+n));
35     return 0;
36 }
原文地址:https://www.cnblogs.com/iiyiyi/p/4715499.html