小于等于n的正整数相加等于m的一个算法问题

fso918 2013-11-25 06:41:08
面试碰到的题,数据结构,算法什么的早忘干净了,没答上来。。。
大神看下这样做行不?
好像用什么动态规划算法挺做的,那个还没看,有会的大神帮个忙啊
/*
* 有集合N={1,2,3……,n},求a1+a2+……+an=m(ai属于N不等于0,i=1,2,……n)的所有组合,m,n都是自然数
*/
public static void func1(int n, int m, int k, int door){
if(n>m) n = m;
if(m==1&&m>=k){
System.out.println("1");
return;
}else if(n==1){
if(m<=door)
System.out.println(m);
return;
}else {
int i = 0;
while(n*i<=m){
if(i>=k){
if(i>0)
System.out.print(i+"+");
func1(n-1,m-i,i,door);
}
i++;
}
}
}
public static void main(String[] args) {
func1(6,6,0,6);
}
...全文
573 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
momoaiyanzi 2013-11-28
  • 打赏
  • 举报
回复
引用 17 楼 fso918 的回复:
[quote=引用 14 楼 momoaiyanzi 的回复:] 我感觉这个问题可以用递归求解。 将问题转换成减法 先求 m-a1是否在数组n中。如果存在ak = m-a1 则 a1+ak=m成立。接下来求解 a1-a2是否存在数组中,如果存在aj = a1-a2,则aj+a2+ak也成立。以此类推。
你这个想法就是将m分为aj+ak,然后将aj和ak分别再如此往下分为aj'、aj''和ak'、aj'',如m=6=2+4=1+1+4=2+1+3等。 如果这样的话不好去重。[/quote] 嗯,确实存在解集重复的问题。 要完成去重的话,就需要做一些其他操作了。对每一个解集做排序,然后存Set。
快乐的2 2013-11-27
  • 打赏
  • 举报
回复
上网找个背包算法去解决这个问题.
momoaiyanzi 2013-11-27
  • 打赏
  • 举报
回复
我感觉这个问题可以用递归求解。 将问题转换成减法 先求 m-a1是否在数组n中。如果存在ak = m-a1 则 a1+ak=m成立。接下来求解 a1-a2是否存在数组中,如果存在aj = a1-a2,则aj+a2+ak也成立。以此类推。
fso918 2013-11-27
  • 打赏
  • 举报
回复
引用 9 楼 groovy2007 的回复:
允许ai重复使用不?比如1+1+1+1=4
允许
fso918 2013-11-27
  • 打赏
  • 举报
回复
引用 8 楼 Mr_WangB 的回复:
6 1+5 2+4 3+3 1+1+4 2+3 2+2+2 1+1+1+3 2+2 1+1+1+1+2 1+1+1+1+1+1 这不是王晓东的那本书上的么
什么书?求书名
fso918 2013-11-27
  • 打赏
  • 举报
回复
引用 7 楼 udbwcso 的回复:

a1  a2   a3.
0   0     0
0   0     1
0   1     0

二进制
不错的想法,有时间再考虑下。如果你有代码的话能发我不?最近事太多
fso918 2013-11-27
  • 打赏
  • 举报
回复
引用 14 楼 momoaiyanzi 的回复:
我感觉这个问题可以用递归求解。 将问题转换成减法 先求 m-a1是否在数组n中。如果存在ak = m-a1 则 a1+ak=m成立。接下来求解 a1-a2是否存在数组中,如果存在aj = a1-a2,则aj+a2+ak也成立。以此类推。
你这个想法就是将m分为aj+ak,然后将aj和ak分别再如此往下分为aj'、aj''和ak'、aj'',如m=6=2+4=1+1+4=2+1+3等。 如果这样的话不好去重。
mr_wangb 2013-11-27
  • 打赏
  • 举报
回复
引用 12 楼 fso918 的回复:
[quote=引用 8 楼 Mr_WangB 的回复:] 6 1+5 2+4 3+3 1+1+4 2+3 2+2+2 1+1+1+3 2+2 1+1+1+1+2 1+1+1+1+1+1 这不是王晓东的那本书上的么
什么书?求书名[/quote] 算法设计与分析(第二版)
fso918 2013-11-26
  • 打赏
  • 举报
回复
引用 1 楼 ganshenml 的回复:
楼主,你要做什么!我什么都没有!
上面的算法会丢掉一些元素,造成输出的表达式不全。下面的算法用数组记住以输出的表达式,再加上每次迭代后的新表达式,就不会出现上面的问题。 public class Suanfa { /* * 有集合N={1,2,3……,n},求a1+a2+……+aj=m(aj属于N)的所有组合,m,n都是自然数 */ public static void func1(int n, int m, int k, int door, int[] a){ if(n>m) n = m; if(m==1&&m>=k){ a[a.length-n]=1; printA(a); return; }else if(n==1){ if(m<=door){ a[a.length-n]=m; printA(a); } return; }else { int i = 0; while(n*i<=m){ if(i>=k){ if(i>0) a[a.length-n]=i; func1(n-1,m-i,i,door,a); } i++; } } } public static void printA(int[] a){ for(int i = 0; i < a.length; i++){ if(a[i]>0&&i!=a.length-1){ System.out.print(a[i]+"+"); }else if(a[i]>0){ System.out.print(a[i]); } } System.out.println(); } public static void main(String[] args) { //func1_1(6,6,0,6); func1(3,6,0,3,new int[3]); } }
fso918 2013-11-26
  • 打赏
  • 举报
回复
引用 1 楼 ganshenml 的回复:
楼主,你要做什么!我什么都没有!
就是对任意的自然数n,m,取任意多个小于等于n的自然数相加,结果等于m,求所有的这种组合。
mr_wangb 2013-11-26
  • 打赏
  • 举报
回复
我还以为是 1+5, 2+4, 的那种?
groovy2007 2013-11-26
  • 打赏
  • 举报
回复
允许ai重复使用不?比如1+1+1+1=4
mr_wangb 2013-11-26
  • 打赏
  • 举报
回复
6 1+5 2+4 3+3 1+1+4 2+3 2+2+2 1+1+1+3 2+2 1+1+1+1+2 1+1+1+1+1+1 这不是王晓东的那本书上的么
尘缘udbwcso 2013-11-26
  • 打赏
  • 举报
回复

a1  a2   a3.
0   0     0
0   0     1
0   1     0

二进制
ganshenml 2013-11-26
  • 打赏
  • 举报
回复
引用 5 楼 fso918 的回复:
[quote=引用 4 楼 ganshenml 的回复:] 然后你上面贴代码是想说明你做出来了?求动态规划算法做?
我觉得这么做有点二笔 想求个其他好的算法,做个列子学习[/quote]我等不搞算法,只解决实际问题,因此特来灌水!
fso918 2013-11-26
  • 打赏
  • 举报
回复
引用 4 楼 ganshenml 的回复:
然后你上面贴代码是想说明你做出来了?求动态规划算法做?
我觉得这么做有点二笔 想求个其他好的算法,做个列子学习
ganshenml 2013-11-26
  • 打赏
  • 举报
回复
然后你上面贴代码是想说明你做出来了?求动态规划算法做?
ganshenml 2013-11-25
  • 打赏
  • 举报
回复
楼主,你要做什么!我什么都没有!

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧