编写程序求:给出一个整数n,一个数组{a1,a2,...,an},将n表示成数组中若干项的和,写出所有的可能。

例如:n=10,数组为{1,8,4,3,5,2},所有的可能为{1,4,3,2},{1,4,5},{8,2},{3,5,2}。

递归就可以解决,给你写个递归式吧;调用方法如下
int a[6]={1,8,4,3,5,2};
int chose[6]={-1,-1,-1,-1,-1,-1};
decompose( a,5,0,10,chose,0);

void print( int *chose , int n ){
for( int i = 0 ; i < n ; ++i )
printf("%d\t",chose[i]);
printf("\n");
}
//参数分别是,背包数组,数组最大下标,当前选到的第k个元素,要求解的和,已选的结果,已选结果的下标
void decompose( int *array , int max , int k , int subn , int *chose , int c ){
if( subn < 0 )
return ;
if( !subn ){
print( chose , c );
}
for( int i = k ; i <= max ; ++i ){
chose[c] = array[i];
decompose( array , max , i+1 , subn-array[i] , chose , c+1 );
chose[c] = -1;
}
}追问

我想知道的是输入一个数据n,数组也很大,用递归也行吗?

追答

那就比较慢了。这算法是n!的,我在给你一个思路吧,对于这种的更快。先对数组排序,然后再使用回溯法,求解的过程中剪枝会很快。

追问

能用回溯法写一下吗?

追答

下面是主要核心程序,给出了调用方式。主函数中调用了自己写的几个函数,快速排序,数组创建,以及输出数组函数,不影响阅读。去掉之后换成自己的就可以了,运行没问题。
int d[]={2,3,4,5,6,7,8,9,10};
GetAllTheCombination( d, 8,12);

//要选的数组,数组最大下标,要求的和m
void GetAllTheCombination( int *array , int n , int m ){
QuickSort( array , 0 , n );
print_array(array,n+1);
int sub = m;
int *chose_array = CreateArray(n);
int i = 0, chose = 0, count = 0;
//i是选择当前已选数的个数-1,chose是array当前中当前要选的数的下标,count记录总的组合法个数
while( i >= 0 ){
if( sub > 0 ){//当前剩余和大于0
if( sub > array[chose] ){//剩余和大于当前选的数
if( chose == n ){//选到了最后一个数
if( i <= 0 )//数组只有一个数,长度为一的话
break;
sub += array[ chose_array[i - 1] ];
chose = chose_array[i - 1] + 1;
--i;
}else{//加入选数,并计算出剩余的数,下一个要选的数,以及记录下一个数的位置
sub -= array[chose];
chose_array[i] = chose;
++chose;
++i;
}
}else if( sub == array[chose] ){//刚好得到了一种选法,并输出
chose_array[i] = chose;
//if( i == 5 ){
printf("array is:\n");
for( int k = 0 ; k <= i ; ++k )
printf("%d\t",array[ chose_array[k] ] );
printf("\n");
++count;
//}
if( i <= 0 )//第一个数刚好就满足,其他的数不用考虑,因为都大于第一个数
break;
sub += array[ chose_array[i - 1] ];//找下一种选法
chose = chose_array[i - 1] + 1;
--i;
}else{//剩余的数小于当前的数,退一步
if( i <= 0 )
break ;
sub += array[ chose_array[i - 1] ];
chose = chose_array[i - 1] + 1;
--i;
}
}else{//剩余的数小于0,退一步
if( i <= 0 )
break ;
sub += array[ chose_array[i - 1] ];
chose = chose_array[i - 1] + 1;
--i;
}
}
printf("the total solutions:%d\n",count);
deleteArray(chose_array);
}

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-09-27
程序我就不写了,麻烦,思路:所有数相加为n,所有数-1相加为n,知道a为 n,取值即可。
第2个回答  2012-09-27
先排序,如果n比较小,暴力搜索。如果n比较大,用回溯法可以
第3个回答  2012-09-27
1+1=几

编写程序求:给出一个整数n,一个数组{a1,a2,...,an},将n表示成数组中若...
printf("\\n");} \/\/参数分别是,背包数组,数组最大下标,当前选到的第k个元素,要求解的和,已选的结果,已选结果的下标 void decompose( int *array , int max , int k , int subn , int *chose , int c ){ if( subn < 0 )return ;if( !subn ){ print( chose , c );} ...

线性表L=(a1, a2, ..., an)用数组表示,假定删除表中任一元素的概率相同...
线性表L=(a1, a2, ..., an)用数组表示,假定删除表中任一元素的概率相同,则删除一个元素平均需要移动元素的_(n-1)\/2__线性表L=(a1, a2, ..., an)用数组表示,假定删除表中任一元素的概率相同,则插入一个元素平均需要移动元素的_n\/2__...

\/\/整数序列a1,a2,a3,….,an,给出求解最大值的递归程序
return m;\/\/返回m } 比如数组arr[3]={2,3,1};调用max(arr,3);是这样的的:调用max(arr,3)由于len=3>1所以求arr[0]和max(arr+1,2)【就是后两个元素的最大值】的最大值 调用max(arr+1,2)由于len=2>1所以求(arr+1)[0]【就是原来的arr[1]】和max(arr+2,1)的最大值 调用m...

六年级下册关于抽屉原理的问题
抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1或多于n+1个元素放到n个集合中去,其中必定至少有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理(“如果有五个鸽子笼,养鸽人养了6只鸽子,那么当鸽子飞回笼中后,至少有一个笼子中装有2只鸽子”)。它...

给定有次序的n个数a1,a2,…,an,记Sk=a1+a2+…+ak(1≤k≤n),称A=S1+...
设第一个数组的凯森和为A1=S1+S2.。。。s99 第二个数组的凯森和为 A2,则A2=21+(21+S1)+(21+S2)+。。。(21+S99)=100+21×100=2200

设有一元素为整数的线性表L=(a1,a2,a3,?,an),存放在一维数组A[N]中...
int main(void) { int arr[45];for (int i = 0; i < 45; ++i) { arr[i] = 45 - i;} int k = 30;printf("k = %d, arr[k] = %d\\n", k, arr[k]);halfSort(arr, 0, 44, k);for (int i = 0; i < 45; ++i) { printf("%d ", arr[i]);} return 0;} ...

c++中给定一个由不同整数a1,a2,…,an按升序排列而成的序列,设计程序确 ...
int main(){ int a[n]={a1,a2,...,an}; \/\/此处定义并且初始化了数组a[n],注意n必须是一个常量 for(int i=0 ; i<n ; i++) \/\/此处循环开始并且历遍数组下标 { if(a[i]==i ) \/\/判断题干条件是否为真 cout<<"存在"<<endl; \/\/如果条件成立,输出“存在“if...

设有一元素为整数的线性表L=(a1,a2,a3,…,an),存放在一维数组A[N]中...
int main(void) { int arr[45];for (int i = 0; i < 45; ++i) { arr[i] = 45 - i;} int k = 30;printf("k = %d, arr[k] = %d\\n", k, arr[k]);halfSort(arr, 0, 44, k);for (int i = 0; i < 45; ++i) { printf("%d ", arr[i]);} return 0;} ...

求动态规划计数例题
现在的问题是,给定n个矩阵{A1,A2,…,An}。其中Ai与Ai+1是可乘的,i=1,2,…,n-1。要求计算出这n个矩阵的连乘积A1A2…An。 递归公式: 程序如下: #include<stdio.h> int main() { int p[101],i,j,k,r,t,n; int m[101][101]; \/\/为了跟讲解时保持一致数组从1开始 int s[101][101]; \/...

有数组(a1,a2,a3,a4,a5,a6),(b1,b2,b3,b4,b5,b6),怎样计算其中任意三...
郭敦顒回答:设A={a1,a2,a3,a4,a5,a6},B={b1,b2,b3,b4,b5,b6},Ci={xi,yi,zi},i=1,2,…,C³下标12=220,且Ci⊂(A∪B),则xi+yi+zi表示其中任意三个值的和。

相似回答