zoukankan      html  css  js  c++  java
  • HDU 1258 Sum It Up DFS 简单题 好题

    给出一个数t,n,然后后面有n个数。

    问:从这n个数里面能不能挑出一些数,使得和为t,注意输出顺序。

    Sample Input
    4 6 4 3 2 2 1 1
    5 3 2 1
    1 400 12 50 50 50 50 50 50 25 25 25 25 25 25
    0 0
     

     

    Sample Output
    Sums of 4:
    4
    3+1
    2+2
    2+1+1
    Sums of 5:
    NONE
    Sums of 400:
    50+50+50+50+50+50+25+25+25+25
    50+50+50+50+50+25+25+25+25+25+25

     

    要满足这种输出顺序,知道预先将数组从大到小排列就OK了。

    dfs(int cnt,int cnr,int sum)

    cnt 表示当前ans数组放进了多少个数字,

    cur 表示当前加进去的数在a数组的位置

    sum 表示当前的和

    用一个pre防止相同的数在相同条件下加进去。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn=1010;
     6 const int inf=0x3f3f3f3f;
     7 int a[maxn];    
     8 int t,n;
     9 bool vis[maxn];  
    10 int ans[maxn];
    11 bool flag;   //判断有没有解
    12 bool cmp(int b,int c)
    13 {
    14     return b>c;   
    15 }
    16 void dfs(int cnt,int cur,int sum)
    17 {
    18     if(sum>t||cnt>n)
    19         return ;
    20     ans[cnt]=a[cur];
    21     if(sum==t)
    22     {
    23         for(int i=1;i<cnt;i++)
    24             printf("%d+",ans[i]);
    25         printf("%d
    ",ans[cnt]);
    26         flag=true;
    27         return ;
    28     }
    29     int pre=inf;    //防止相同的数在相同的条件下加进去
    30     for(int i=cur+1;i<=n;i++)
    31     {
    32         if(!vis[i]&&a[i]!=pre){
    33             vis[i]=true;
    34             pre=a[i];        //及时更新
    35             dfs(cnt+1,i,sum+a[i]);
    36             vis[i]=false;    //回溯
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     while(scanf("%d%d",&t,&n))
    43     {
    44         if(t==0&&n==0)
    45             break;
    46         for(int i=1;i<=n;i++)
    47             scanf("%d",&a[i]);
    48         memset(vis,false,sizeof(vis));   //初始化
    49         sort(a+1,a+n+1,cmp);
    50         a[0]=inf;     
    51         flag=false;   //假设没有解,找到解后为true
    52         printf("Sums of %d:
    ",t);
    53         int pre=inf;
    54         for(int i=1;i<=n;i++)
    55         {
    56             if(a[i]!=pre)
    57             {
    58                 vis[i]=true;
    59                 dfs(1,i,a[i]);
    60                 vis[i]=false;    //回溯
    61                 pre=a[i];       
    62             }
    63         }
    64         if(!flag)
    65             printf("NONE
    ");
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/-maybe/p/4395151.html
Copyright © 2011-2022 走看看