• 【穷竭】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 }
  • 相关阅读:
    文档驱动开发模式在 AIMS 中的应用与实践
    软件“美不美”,UI测试一下就知道
    做运维,送你7个常用的服务器资源监控工具
    掌握ROMA Compose,报表清单不秃头
    技术干货丨隐私保护下的迁移算法
    业务爆发式增长,音视频服务如何做好质量监控与优化?
    MyBatis中SQL语句优化小结
    Go语言微服务开发框架:Go chassis
    揭开KPI异常检测顶级AI模型面纱
    激光雷达lidar与点云数据
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/4715499.html
Copyright © 2020-2023  润新知