zoukankan      html  css  js  c++  java
  • 子集和问题

    题目描述

    对于一个给定正整数的集合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

    提示

    这道题需要剪枝才能AC,剪枝方法是计算出后缀和数组sum[i]和最小值数组mina[i].在进行枚举时增加逻辑如下:如果当前已选中元素和加上sum[i]小于c,或者当前已选中元素和加上mina[i]大于c,直接返回即可。 
     
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    long long n,m,ans[7001],a[7001],sum[7001],minn[70001];
    bool chu=0;
    void dfs(int k,int chang,int he)
    {
        if(he==m)
        {
            for(int i=0;i<chang;i++)
            {
                printf("%d ",ans[i]);
            }
            chu=1;
            return;
        }
        if((k==n||he+sum[k]<m||he+minn[k]>m))
        return;
         
        if(chu==1)
        return;
        if(he+a[k]<=m)
        {
            ans[chang]=a[k];
            dfs(k+1,chang+1,he+a[k]);
        }
            dfs(k+1,chang,he);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sum[n-1]=a[n-1];minn[n-1]=a[n-1];
        for(int i=n-2;i>=0;i--)
        {
            sum[i]=a[i]+sum[i+1];
            minn[i]=1000000000;
            minn[i]=min(minn[i+1],a[i]);
        }
        dfs(0,0,0);
        if(chu==0)
        {
            printf("No Solution!");
        }
    }
  • 相关阅读:
    通过命令行指定 Java 程序运行时使用的字符集
    Ubuntu Linux 开启 root 用户及其它登录问题的解决
    SLF4J 的几种实际应用模式 SLF4J+Log4J 与 SLF4J+LogBack
    Java 获取当前时间的年月日方法
    Eclipse 全屏插件
    Linux 下的纯 C 日志函数库: zlog
    如何使用 Log4j
    DAO 设计模式
    为什么要用 /dev/null 2>&1 这样的写法
    NSDate和NSString之间的转换
  • 原文地址:https://www.cnblogs.com/fanhao050109/p/11191823.html
Copyright © 2011-2022 走看看