zoukankan      html  css  js  c++  java
  • 7.1 深搜子集和问题 (枚举子集+剪枝)

    ---恢复内容开始---

    7.1,今日AC题目5到,今天为大家讲解一道普及组的深搜剪枝问题,这道题参解时需要在脑海及对应的手上模拟,切忌眼高手低,切忌三心二意

    题目描述

    对于一个给定正整数的集合s={x1,x2,x3…xn}和正整数c,编程计算s的第一个子集s1,使得子集s1的和等于c。

     

    输入

    第一行有2个正整数n和c
    第二行有n个正整数
    n<7000,c<maxlongint


    输出

    一行数据,按输入的顺序输出,若无解则输出"No Solution!"
     

    样例输入

    5 10
    2 2 6 5 4

    样例输出

    2 2 6

    题解:
      这道题的基本解题思想是用dfs枚举数组,计算数组的和。
      但若是数据较大耗时较长,我们便须用剪枝来优化,对应的剪枝方法:
        1.计算出后缀和数组sum[i]和后缀最小值数组mina[i]
        2.对于sum[i]数组,在枚举过程中若是当前数组和cnt加上i的后缀和sum[i]小于c,则直接break跳出循环,当前dfs状态结束
        3.对于mina[i]数组,在枚举过程中若是当前数组和cnt加上mina[i]>c,也是直接跳出循环,当前dfs状态结束,跳入下一状态

    题解代码:

    #include<iostream>
    #include<string>
    using namespace std;
    int n;
    long long c,a[7005],sum[7005],mina[7005],ans[7005],minn=0x3f3f3f3f,sum1=0;
    bool flag=0;
    void dfs(int index1,int index2,int cnt){
     if(cnt>c) return ;
     if(cnt==c){
      for(int i=0;i<index2;i++){
       printf("%lld ",ans[i]);
      }printf("\n");
      exit(0);
     }
     for(int i=index1+1;i<n;i++){
      if(cnt+sum[i]<c) break;
      if(cnt+mina[i]>c) break;
      ans[index2]=a[i];
      dfs(i,index2+1,cnt+ans[index2]);
     }
    }
    int main(){
     freopen("setsum.in","r",stdin);
     scanf("%d%lld",&n,&c);
     for(int i=0;i<n;i++){
      scanf("%lld",&a[i]);
     }
     for(int i=n-1;i>=0;i--){
      minn=min(minn,a[i]);
      sum1+=a[i];
      sum[i]=sum1;
      mina[i]=minn;
     }
     /*
     for(int i=0;i<n;i++){
      printf("%lld %lld\n",sum[i],mina[i]);
     }
     */
     dfs(-1,0,0);
     printf("No Solution!\n");
     
     return 0;
    }


    反省与展望:
      7.1日记住这一天,正如孙老师所说:追求卓越,成功便会在不经意间与你相遇
      当今段位usaco青铜,坚持每天进步一点点,哪怕多刷一道题,多学10分钟英语,与樊浩,李俊辉大佬共同进步,争取早日超过孙西越大佬
      争取早日拿下usaco金级段位,信息学竞赛,传统算法高级人才稀缺,高级教育人才有价无市,咸鱼翻身的机会就在眼前,哪怕只有一次机会,都应全力以赴
      如今的我只能辅导入门组,而入门组能辅导的人太多了,争取在暑假尽快提升自我,将普及组的题刷完,辅导普及组,提升自我在第一位,挣钱在第二位,要挣就挣个大的。
      博观而约取,厚积而薄发。

    ---恢复内容结束---

  • 相关阅读:
    bzoj 1208: [HNOI2004]宠物收养所 (Treap)
    Bzoj 2431: [HAOI2009]逆序对数列 (DP)
    Bzoj 1055: [HAOI2008]玩具取名 (区间DP)
    线段树入门详解
    Bzoj 1087: [SCOI2005]互不侵犯King
    Bzoj 2748: [HAOI2012]音量调节 (DP)
    Bzoj 2752 高速公路 (期望,线段树)
    惨淡的模拟赛
    GSS4
    Bzoj 近期题目一句话题解
  • 原文地址:https://www.cnblogs.com/cxs070998/p/11117549.html
Copyright © 2011-2022 走看看