• 洛谷P1118数字三角型(全排列+数学杨辉三角计算优化)


    题目链接:https://www.luogu.org/problemnew/show/P1118

    这题直接用全排列会超时,需要找出规律,用杨辉三角计算规律优化。

    假设一个排列数字用a,b,c,d....代替,那么它最终的和是有规律的:

    如果n为4,那么sum是a+3b+3c+d。

    如果n为5,那么sum是a+4b+6c+4d+e。

    如果n为6,那么sum是a+5b+10c+10d+5e+f。

    即排列到哪个数,我们就能快速算出(O(1))目前为止这个排列最终的和,而不用一步一步模拟求和下去,节省了很多的时间

    70,直接暴力全排列判断和

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int vis[maxn],used[maxn],t[maxn];
    13 int n,sum,f;
    14 int js()
    15 {
    16     for(int i=1;i<=n;i++) t[i]=used[i];
    17     for(int i=n;i>1;i--)
    18     {
    19         for(int j=1;j<=i-1;j++)
    20         {
    21             t[j]+=t[j+1];
    22         }
    23     }
    24 
    25     return t[1];
    26 }
    27 
    28 
    29 void so(int step)
    30 {
    31     if(f) return;
    32     if(step==n+1)
    33     {
    34         int ans=js();
    35         if(ans==sum)
    36         {
    37             for(int i=1;i<=n-1;i++) cout<<used[i]<<' ';
    38             cout<<used[n]<<endl;
    39             f=1;
    40         }
    41         return;
    42     }
    43 
    44     for(int i=1;i<=n;i++)
    45     {
    46         if(!vis[i])
    47         {
    48             vis[i]=1;
    49             used[step]=i;
    50             so(step+1);
    51             vis[i]=0;
    52         }
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     ios::sync_with_stdio(false); cin.tie(0);
    59 
    60     cin>>n>>sum;
    61 
    62     so(1);
    63 
    64     return 0;
    65 }
     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int vis[maxn],used[maxn],t[maxn];
    13 int n,sum,f;
    14 int js()
    15 {
    16     for(int i=1;i<=n;i++) t[i]=used[i];
    17     for(int i=n;i>1;i--)
    18     {
    19         for(int j=1;j<=i-1;j++)
    20         {
    21             t[j]+=t[j+1];
    22         }
    23     }
    24 
    25     return t[1];
    26 }
    27 
    28 
    29 void so(int step)
    30 {
    31     if(f) return;
    32     if(step==n+1)
    33     {
    34         int ans=js();
    35         if(ans==sum)
    36         {
    37             for(int i=1;i<=n-1;i++) cout<<used[i]<<' ';
    38             cout<<used[n]<<endl;
    39             f=1;
    40         }
    41         return;
    42     }
    43 
    44     for(int i=1;i<=n;i++)
    45     {
    46         if(!vis[i])
    47         {
    48             vis[i]=1;
    49             used[step]=i;
    50             so(step+1);
    51             vis[i]=0;
    52         }
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     ios::sync_with_stdio(false); cin.tie(0);
    59 
    60     cin>>n>>sum;
    61 
    62     so(1);
    63 
    64     return 0;
    65 }

    60,剪枝后60分...可能是每次计算太花费时间

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int vis[maxn],used[maxn],t[maxn];
    13 int n,sum,f;
    14 int js(int n)
    15 {
    16     for(int i=1;i<=n;i++) t[i]=used[i];
    17     for(int i=n;i>1;i--)
    18     {
    19         for(int j=1;j<=i-1;j++)
    20         {
    21             t[j]+=t[j+1];
    22         }
    23     }
    24 
    25     return t[1];
    26 }
    27 
    28 
    29 void so(int step,int ans)
    30 {
    31     if(f || ans>sum) return;
    32     if(step==n+1 && ans==sum)
    33     {
    34         for(int i=1;i<=n-1;i++) cout<<used[i]<<' ';
    35         cout<<used[n]<<endl;
    36         f=1;
    37         return;
    38     }
    39 
    40     for(int i=1;i<=n;i++)
    41     {
    42         if(!vis[i])
    43         {
    44             vis[i]=1;
    45             used[step]=i;
    46             so(step+1,js(step));
    47             vis[i]=0;
    48         }
    49     }
    50 }
    51 
    52 int main()
    53 {
    54     ios::sync_with_stdio(false); cin.tie(0);
    55 
    56     cin>>n>>sum;
    57 
    58     so(1,0);
    59 
    60     return 0;
    61 }

    100,看题解明白用杨辉三角数学方式找规律计算....

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int vis[maxn],used[maxn];
    13 int yh[1005][1005];
    14 int n,sum,f;
    15 
    16 void so(int step,int ans)
    17 {
    18     if(f || ans>sum) return;
    19     if(step==n+1 && ans==sum)
    20     {
    21         for(int i=1;i<=n-1;i++) cout<<used[i]<<' ';
    22         cout<<used[n]<<endl;
    23         f=1;
    24         return;
    25     }
    26 
    27     for(int i=1;i<=n;i++)
    28     {
    29         if(!vis[i])
    30         {
    31             vis[i]=1;
    32             used[step]=i;
    33             so(step+1,ans+used[step]*yh[n][step]);//或者i*yh[n][step]
    34             vis[i]=0;
    35         }
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     ios::sync_with_stdio(false); cin.tie(0);
    42 
    43     cin>>n>>sum;
    44 
    45     yh[1][1]=1;//构造杨辉三角型
    46     for(int i=2;i<=n;i++)
    47     {
    48         for(int j=1;j<=i+1;j++)
    49         {
    50             yh[i][j]=yh[i-1][j-1]+yh[i-1][j];
    51         }
    52     }
    53 
    54     so(1,0);
    55 
    56     return 0;
    57 }

    完。

  • 相关阅读:
    TWinHttp之二
    日志池
    TWinHTTP
    TJSONTableObject跨平台解析JSON
    TSQLTableJSON解析JSON
    TDocVariantData解析JSON
    Vue.js常用指令汇总(v-if//v-show//v-else//v-for//v-bind//v-on等)
    VUE -- 十分钟入门 Less
    VUE -- ejs模板的书写
    Go VUE --- vuejs在服务器部署?
  • 原文地址:https://www.cnblogs.com/redblackk/p/9849142.html
Copyright © 2020-2023  润新知