寻找和为定值的任意个数(01背包)
来源:互联网 发布:淘宝火车票网上订票 编辑:程序博客网 时间:2024/06/03 03:45
这个问题是在July的《编程之法》上看到的,题目要求是:输入两个数字n与sum,在1~n中寻找哪些数字之和等于sum。
很明显这是个典型的01背包问题,因为每一个元素只有要与不要两种选择~
#include<list> #include<iostream> using namespace std; list<int>list1; void find_factor(int sum, int n) { // 递归出口 if(n <= 0 || sum <= 0) return; if(n>sum) n=sum; // 输出找到的结果 if(sum == n) { // 反转list list1.reverse(); for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++) cout << *iter << " + "; cout << n << endl; list1.reverse(); } list1.push_front(n); //典型的01背包问题 find_factor(sum-n, n-1); //放n,n-1个数填满sum-n list1.pop_front(); find_factor(sum, n-1); //不放n,n-1个数填满sum } int main() { int sum, n; cout << "请输入你要等于多少的数值sum:" << endl; cin >> sum; cout << "请输入你要从1.....n数列中取值的n:" << endl; cin >> n; cout << "所有可能的序列,如下:" << endl; find_factor(sum,n); return 0; }
后来自己又在想,这样局限性有点大,如果数组元素是任意的呢?即:数组元素任意,输入sum,求所有和为sum的组合
可以思考一下:若数组元素任意,则处理之前,必须进行排序(原本可能是无序的),使用快速排序实现此功能。然后实际上还是一个背包问题,只不过不是01背包,可以说算是完全背包吧,因为每个元素科可以有多个,但是在逻辑上仍然将它们看作是单独的存在,两种选择:要或不要,在上边代码的基础上进行改进:
#include<iostream>#include<cstdio>#include<list>using namespace std;list<int> list1;int number; //统计总共多少种符合要求的组合 int find(int s[],int sum){ //在数组s中寻找比sum小的最大的一个元素的下标,若不存在则返回-1 int i;for (i=0;s[i]<=sum&&i<10;i++);return i-1;}void swap(int *a,int *b){ //交换数组中两个元素的下标 int t;t=*a;*a=*b;*b=t;}void sort(int s[],int left,int right){ //快速排序 if(left>=right) return ;int i,j,mid;mid =(left+right)/2;swap(&s[left],&s[mid]);for(j=left,i=left+1;i<=right;i++)if(s[i]<s[left]){swap(&s[i],&s[++j]);}swap(&s[left],&s[j]);sort(s,left,j-1);sort(s,j+1,right);}void find_factor(int s[],int sum,int n){ if(n==-1) //n==-1则相当于:s[0]被考虑过(包含加或不加)后仍旧不能满足sum,即之前的组合状态不可行,直接返回。 return ;if(sum<s[n]){ //如果sum小于当前区域内的最大元素,则执行find()函数找到小于它的最后一个元素,若找不到,则说明在 n=find(s,sum); // 之前的组合状态不可行,直接返回。 if(n==-1) return; }if(sum==s[n]){ //说明之前的组合状态可行 number++; //统计所有符合要求的组合的个数 list1.reverse(); //反转list for(list<int>::iterator iter =list1.begin();iter!=list1.end();iter++)cout<<*iter<<"+";cout<<s[n]<<endl;list1.reverse(); }list1.push_front(s[n]); //非常典型的01背包问问题 find_factor(s,sum-s[n],n-1);//放s[n],用剩余n-1个元素 填满 sum-s[n] list1.pop_front();find_factor(s,sum,n-1); //不放s[n],用剩余n-1个元素 填满 sum} int main(void){int i,j,k,sum;int s[10];printf("请输入想要的sum:\n");scanf("%d",&sum);printf("请输入数组元素:\n");for(i=0;i<10;i++)scanf("%d",s+i);sort(s,0,9); //快排 /*for(i=0;i<10;i++){printf("%d ",s[i]);}*/ printf("符合要求的组合:\n");find_factor(s,sum,9);printf("总共%d种组合\n",number); return 0;}
如此。
0 0
- 寻找和为定值的任意个数(01背包)
- 寻找和为定值的多个数
- 寻找满足和为定值的多个数
- 寻找和为定值的两个数/多个数
- 寻找和为定值的两个或多个数
- 寻找和为定值的多个数
- 【编程练习】寻找和为定值的多个数
- 寻找和为定值的多个数
- 寻找和为定值的多个数
- 寻找和为定值的多个数
- 【算法】寻找和为定值的多个数
- 寻找和为定值的多个数
- 寻找和为定值的多个数
- github-july-寻找和为定值的多个数
- 寻找和为定值的多个数
- 寻找和为定值的多个数
- 寻找和为定值的N个数
- 寻找和为定值的多个数
- SpringMVC 返回字符串
- idea无法调试的解决方案。之一。
- IDEA的Maven中使用EL表达式
- python的MySqldb使用
- 使用RandomAccessFile获取文件的MD5值
- 寻找和为定值的任意个数(01背包)
- iOS 【Multithreading-线程间的交互通信(图片下载示例)(掌握)】
- ios基本图形绘制
- 建造者模式
- Java笔记9:Spring简单Demo
- 【LeetCode OJ 258】Add Digits
- Android性能优化之Splash页应该这样设计
- python join字符连接函数的使用方法
- mysql报错问题解决MySQL server PID file could not be found!