博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
子集和的另外一个问题
阅读量:6627 次
发布时间:2019-06-25

本文共 2007 字,大约阅读时间需要 6 分钟。

子集和是一个很著名的问题, 

一个集合S{s1,s2,s3,s3,...,sn}, 给一个数s,问是否存在一个S的一个或多个子集,使得该子集内所有元素的和等于给出的数.

显然利用一个辅助的数字x[],可以在O(2^n)时间复杂度内完成搜索出所有的解.

当如果要问存在多少个子集能够组成目标数字. 我们可以利用动态规划的方法来得到答案, 这样时间和空间复杂度是O(s*n), s是目标数字, n是备选集合的元素个数.

动态方程是: f(i, j) =f(i-1, j) + f(i-1, j-S[i-1]) + (j==S[i]). 其中i从1到n, j从1到s.

最终结果f(n,s)就是可以组成s的子集个数.

----

import java.util.Arrays;public class SumOfSub {    int num=0;    public void solve(int a[], int s, int x[], int i){        if(i==x.length){            return;        }        x[i]=1;        int sum=0;        int j;        for(j=0;j<=i;j++){            sum+=a[j]*x[j];        }        if(sum==s){            System.out.println("Find Solution "+num+" "+Arrays.toString(x));            num++;        }        solve(a,s,x,i+1);        x[i]=0;        solve(a,s,x,i+1);    }    public void solveUsingDp(int a[], int s){        int n=a.length;        int c[][]=new int[n+1][s+1];        for(int i=1;i<=n;i++){            for(int j=1;j<=s;j++){                if(j>=a[i-1]){                    c[i][j]=c[i-1][j]+c[i-1][j-a[i-1]];                    if(j==a[i-1]){                        c[i][j]+=1;                    }                }                else                     c[i][j]=c[i-1][j];            }        }        System.out.println("Total Solution num: "+c[n][s]);    }    public static void main(String args[]){        SumOfSub ss=new SumOfSub();        int a[]=new int[]{3,5,8,2,7,1,6};        int s=14;        int x[]=new int[7];        ss.solve(a, s, x, 0);        System.out.println(ss.num);        ss.solveUsingDp(a, s);    }}

 

-----

 

这两天看topcoder上SRM 548 div1的第二题, 想到了另外一个子集和相关的问题. 就是:

在组成s的所有子集中, 元素个数最少的那个子集所含元素个数是什么?

当然, 利用第一种搜索的方式可以的得到答案, 但时间复杂度太高. 如果n稍微大一些, 则搜索过程会很漫长. 有没有更好的方法呢?

tc网站上给出了一种很好的方法, 两重循环就可以搞定.

具体来说就是 先将S集合升序排序, 然后利用一个cnt[]数组, 数组长度为s, cnt[i]意思为表示数字i的所有子集的元素个数最小的那个的元素个数.cnt[0]=0. 

初始化cnt[1]~cnt[n-1]=n+1;

 for(i=0;i<S.length; i++){

for(j=1;j<=s;j++){

if(j>=S[i]) cnt[j]=min(cnt[j], cnt[j-S[i]]+1);

}

}

转载于:https://www.cnblogs.com/gaoqichao/archive/2012/08/02/2619673.html

你可能感兴趣的文章
Codeforces 433 C. Ryouko&#39;s Memory Note
查看>>
java中的Static class
查看>>
实例讲解Linux下的makefile
查看>>
json lib 2.4及其依赖包下载
查看>>
计算机中文核心期刊
查看>>
【BZOJ】3832: [Poi2014]Rally
查看>>
[转]看懂ExtJS的API
查看>>
推荐15款制作 SVG 动画的 JavaScript 库
查看>>
转:CEO, CFO, CIO, CTO, CSO是什么
查看>>
andriod自定义视图
查看>>
linux下vim更改注释颜色
查看>>
在SSL / https下托管SignalR
查看>>
Using JRuby with Maven
查看>>
Netty了解与小试
查看>>
醒醒吧少年,只用Cucumber不能帮助你BDD
查看>>
一名女程序员对iOS的想法
查看>>
西班牙现新型电费退款网络诈骗 侨胞需谨防上当
查看>>
Spring Websocket实现文本、图片、声音、文件下载及推送、接收及显示(集群模式)...
查看>>
最严新规发布 网络短视频平台该如何降低违规风险? ...
查看>>
云服务器ECS出现速度变慢 以及突然断开怎么办?
查看>>