200分求助C#算法。各位算法高手帮帮忙!谢谢

wl076 2015-12-30 03:11:15
一组数据{1,2,3,4,5,6,7,8,9,10,11,12} 里面若干个数相加等于15,列出所有可能,比如
1+2+12=15
1+3+11=15
1+2+3+4+5=15
7+8=15
2+3+10=15
...
...全文
179 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
caojinrong 2015-12-31
  • 打赏
  • 举报
回复
垃圾app,全乱了,有空找台电脑发
caojinrong 2015-12-31
  • 打赏
  • 举报
回复
思考了一下,可以这么做,由于手头没有计算机,只能用文字描述了。 设15=a1+a2+... 其中每项取值ai>=1&&ai<=12且a1<a2<a3<... 采用递归方式求解,原型为: void Fun(int[] para,List<List<int>> result); para表示当前分解式,result保存符合要求的分解式。因为15=1+14不属于结果集,但其二次分解式15=1+2+12属于结果集,故作此处理。方法体实现把当前分解式[a1,a2,...,an1,an]的最后一项an分解为an2+an3,且an1<an2<an3,把新分解式保存到作为参数进行递归,如果an3<=12,把结果保存至result。 void Fun(int[] para,List<int[]> result) { if(para == null || para.Length == 0) return; //容错处理,本人习惯,无实际用途,防止别人使用时参数给错 int min = para.Length > 1 ? para[para.Length - 2] : 0; //分解式最小值 int a1 = para[para.Length - 1]; //仅对最后一项进行分解 //分解,第一项a2必须大于min小于等于a1/2 for(int a2 = min + 1;a2 <= a1 / 2;a2++) { int[] tmp = new int[para.Length + 1]; Array.Copy(tmp,para,para.Length); tmp[para.Length - 1] = a2; int a3 = tmp[para.Length] = a1 - a2; if(a3 <= 12) result.Add(tmp); Fun(tmp,result); } } 调用代码如下: List<int[]> result = new List<int[]>(); Fun(new int[]{15},result); 在手机上硬点出来的,楼主自己试试看吧,应该没什么问题,时间复杂度是最小的。
caojinrong 2015-12-30
  • 打赏
  • 举报
回复
引用 1 楼 shingoscar 的回复:
不就是求一个集合里所有可能的组合么?
估计楼主就是散分来的 求组合也可理解为求分解,可根据以下原则降低时间复杂度: 1、15是奇数,故分解式中至少包含一个奇数,取该数为1、3、5...11,得到一级分解式3+12、...、11+4 2、对一级分解式中第二个数(偶数)进行二次分解....
Poopaye 2015-12-30
  • 打赏
  • 举报
回复
		void Run()
		{
			int[] collection = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

			foreach (var item in GetDistinctResult(collection, 15))
			{
				Console.WriteLine(string.Join(" + ", item));
			}
		}

		IEnumerable<int[]> GetDistinctResult(int[] collection, int sum)
		{
			return GetResult(collection, sum).Distinct();
		}

		IEnumerable<int[]> GetResult(int[] collection, int sum)
		{
			for (int count = 1; count <= collection.Length; ++count)
				foreach (var item in Fill(count, 0, collection, new int[count]))
					if (item.Sum() == sum)
						yield return item;
		}

		IEnumerable<int[]> Fill(int count, int start, int[] collection, int[] selection)
		{
			int num = count - 1;
			int upper = collection.Length - num;
			for (int i = start; i < upper; ++i)
			{
				selection[selection.Length - count] = collection[i];
				if (num == 0)
					yield return (int[])selection.Clone();
				else
					foreach (var item in Fill(num, i + 1, collection, selection))
						yield return item;
			}
		}
wl076 2015-12-30
  • 打赏
  • 举报
回复
引用 2 楼 hebiao89757 的回复:
for (int i = sum - 1; i > 0; --i) { sumcount(i, i); } int sum = 12; int cnt = 0;//计数 public void sumcount(int s,int n){ for(int i = n-1; i >= 1; --i){ if(s+i == 15){ ++cnt; } else if(s+i < sum){ sumcount(s+i,i); } } }
我想实现的是若干个数字相加并不是两个数学相加。
hebiao89757 2015-12-30
  • 打赏
  • 举报
回复
for (int i = sum - 1; i > 0; --i) { sumcount(i, i); } int sum = 12; int cnt = 0;//计数 public void sumcount(int s,int n){ for(int i = n-1; i >= 1; --i){ if(s+i == 15){ ++cnt; } else if(s+i < sum){ sumcount(s+i,i); } } }
Poopaye 2015-12-30
  • 打赏
  • 举报
回复
不就是求一个集合里所有可能的组合么?

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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