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 }