zoukankan      html  css  js  c++  java
  • 1到n数组,和为指定数所有序列问题

    (1)方法一,背包问题解法

     1 #include  <iostream>
     2 using namespace std;
     3 #include <vector>
     4 #include <list>
     5 
     6 //采用背包问题方法,从后向前,最后一个放和不放背包里,注意递归退出条件和sum==n后,没有return而是继续
     7 vector<int> a;   //存背包 事实证明用vector就可以,也不用revers。
     8 
     9 void subofsum(int sum,int n,bool &flag)
    10 {
    11     if(sum<=0||n<=0)             //迭代退出条件
    12         return;
    13     if(sum==n)
    14     {
    15 
    16         for(vector<int>::iterator i=a.begin();i!=a.end();i++)
    17         {
    18             cout<<*i<<"+";
    19             flag=true;
    20         }
    21         cout<<n<<endl;                  //注意n没有放入背包,而是输出了,而且后面没有return,让n接着放入背包,肯定不行,就会弹出北包,放subofsum(sum,n-1,flag);
    22         
    23     }
    24     a.push_back(n);
    25     subofsum(sum-n,n-1,flag);
    26     a.pop_back();
    27     subofsum(sum,n-1,flag);
    28 }
    29 
    30 int main()
    31 {
    32     int sum=13;
    33     int n=9;
    34     bool flag=false;
    35     subofsum(sum,n,flag);
    36     if(flag==false)
    37     {
    38         cout<<"not found"<<endl;
    39     }
    40     system("PAUSE");
    41 }

    方法二:子集和问题方法,其实跟背包问题差不多。

    自己实现的,原来看懂跟自己能写对差距好大啊,自己写就费了很大劲。真的要练习才行,光看是没用的,只能眼高手地。

    问题:思路很简单,回溯方法,加上修建树枝。

    我做的是t ,k ,当t+k==m,

    t+k<m,t+k+1<=m&&t+r-k>=m

    常规还可以用vector直接放每一个数字,而不是用类似bitmap方法,那种也可以直接用下面的改写,但是空间占用比较多。

     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <string.h>            //memset  must include string.h or ctring
     4 using namespace std;
     5 
     6 /*
     7  * 
     8  */
     9 void subofsum(int t,int k,int r,bool *array,int n,bool &flag,int sum)
    10 {
    11  //   if(k>n)           //这里开始担心k会越界,实际上不会,因为有剪支12  //       return;
    13     //array[k]=true;
    14     if(t+k==sum)          //注意k没有至位
    15     {
    16         for(int i=1;i<=n;i++)            //注意这里是n,july写的是k,想得周到,但这是常规方法
    17         {
    18             if(array[i]==true)
    19             {
    20                 cout<<i<<"+";
    21             }
    22         }
    23         cout<<k<<endl;      //cout k
    24         flag=true;
               return; //可以返回了
    25 } 26 //array[k]=false;           //这里往下有两种情况,都是针对t+k《m的情况,t+k如果大于m直接就跳过两个if了,也就是上面return了,一样。 27 if(t+k<sum)               //只有当t+k《sum时才至位,上来就一直小于一直至位,知道发现不行了或等于了,推出上一层,看另外情况 28 { 29 array[k]=true; //k set 1 30 subofsum(t+k,k+1,r-k,array,n,flag,sum); 31 array[k]=false; //k not set 1 ;normal 在把k恢复,这是常规方法
               if(t+k+1<=sum&&t+r-k>=sum)   //另一种情况 35    { 37 subofsum(t,k+1,r-k,array,n,flag,sum); 38    }
           }
    34 39 }
    40 
    41 int main(int argc, char** argv) {
    42 
    43     int sum=13;
    44     int n=9;
    45     cout<<"sum= "<<"n= "<<endl;
    46     cin>>sum>>n;
    47     if(n<=0||sum<=0)   //这里只有当n《=0时,说明错了,sum可以比n小,也可以比n大,但是sum不能是负数
    48         return 1;
    49     bool * array=new bool[n+1];
    50     //bool array[10]={0};
    51     memset(array,0,sizeof(bool)*(n+1));
    52     bool flag=false;
    53     int r=n*(n+1)/2;
    54     subofsum(0,1,r,array,n,flag,sum);
    55     if(!flag)
    56         cout<<"nof found"<<endl;
    57     return 0;
    58 }

    july博客方法实现

     1 void subofsum(int t,int k,int r,bool *array,int n,bool &flag,int sum)
     2 {
     3  //   if(k>n)           //because have cut ,so k won't > n,k not set 1
     4  //       return;
     5     array[k]=true;           //注意上来就至位了
     6     if(t+k==sum)
     7     {
     8         for(int i=1;i<=k;i++)    //这是关键,只是到k,因为上来就至位,又没有恢复,就会导致后面可能还有1,所以他只用到k,很巧妙,但不常见    
     9         {
    10             if(array[i]==true)
    11             {
    12                 cout<<i<<"";   //最后会多输出一个空格
    13             }
    14         }
    15         cout<<endl;
    16         flag=true;
    17         return;
    18     }
    19     else                       //else可以不用写,上面return了,就算不return也可以不用写else,因为如果上面成立,下面都不会成立
    20     {
    21        if(t+k+k+1<=sum)           //多看个k+1
    22        {
    23         subofsum(t+k,k+1,r-k,array,n,flag,sum);
    24        }
    25        if(t+k+1<=sum&&t+r-k>=sum)
    26        {
    27          array[k]=false; 
    28          subofsum(t,k+1,r-k,array,n,flag,sum);
    29        }
    30    }  
    31 }

    总结:一定要自己动手实习,这样才能真正弄明白自己,可能之前一直没注意到的细节,不能眼高手地啊!

  • 相关阅读:
    zabbix监控docker
    Ubuntu下Zabbix结合percona监控mysql数据
    centos7安装ftp
    Ubuntu 16.04 搭建 ELK
    ubuntu网卡配置及安装ssh服务
    CentOS7.5二进制安装MySQL-5.6.40
    生产环境MySQL数据库集群MHA上线实施方案
    Mysql主从复制
    GIt+jenkins代码自动上线
    虚拟机网卡丢失解决方法
  • 原文地址:https://www.cnblogs.com/zmlctt/p/3832749.html
Copyright © 2011-2022 走看看