回溯法解组合问题——硬币问题
2012-09-25 12:09
246 查看
问题:
1,你有(足够的)5分,2分,1分的硬币,现在要凑出来12分的结果,那么最少的硬币组合是?
2,如果有5,12,7,-5,-7,-12这六个硬币。现在要你凑0-2000以内的任意数又该如何组合呢?
用回溯法解组合问题。在解空间中搜索。
1,你有(足够的)5分,2分,1分的硬币,现在要凑出来12分的结果,那么最少的硬币组合是?
2,如果有5,12,7,-5,-7,-12这六个硬币。现在要你凑0-2000以内的任意数又该如何组合呢?
用回溯法解组合问题。在解空间中搜索。
// MoneyCount.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <vector> #include <iostream> #include <algorithm> #include <time.h> using namespace std; vector<int> MoneyKind; int Total=0; vector<int> bestSolution; //最优解 int flag=0; //用来判断是否第一次找到可行解 //solution 存有问题的当前解 //total 目前还是需要多少 //x 为增加哪一个硬币 void FindSolution( vector<int> & solution, int total, int x ) { if( total == x ) //找到了一个可行解 { if( flag == 0 ) { bestSolution = solution; flag = 1; } else { if( solution.size() < bestSolution.size() ) bestSolution = solution; } return; } //搜索每一个子节点 total = total - x; for( int i=0; i<(int)MoneyKind.size(); i++ ) { solution.push_back( MoneyKind[i] ); if( MoneyKind[i]<=total ) //可行性约束 { if( flag==1 && solution.size() <= bestSolution.size() ) FindSolution( solution, total ,MoneyKind[i] ); if( flag==0) //没有找到可行解 FindSolution( solution, total ,MoneyKind[i] ); } solution.pop_back(); } } void input() { int numKinds=0; cout << "How many kinds of coins?\n"; cin >> numKinds; //MoneyKind.resize( numKinds ); cout << "Input all kinds of coins:\n"; for( int i=0; i<numKinds; i++) { int m=0; cin >> m; MoneyKind.push_back(m); } // sort(MoneyKind.begin(), MoneyKind.end()); cout << "Input the total money of coins:\n"; cin >> Total; } int _tmain(int argc, _TCHAR* argv[]) { input(); clock_t begin = clock(); vector<int> solution; for( int i=0; i<(int)MoneyKind.size(); i++ ) { solution.push_back( MoneyKind[i] ); if( MoneyKind[i]<=Total ) //可行性约束 { if( flag==1 && solution.size() <= bestSolution.size() ) FindSolution( solution, Total ,MoneyKind[i] ); if( flag==0 ) //没有找到可行解 FindSolution( solution, Total ,MoneyKind[i] ); } solution.pop_back(); } if( flag == 0 ) cout << "NO SOLUTION!" <<endl; else { cout << "SOLUTION IS:\n" ; sort( bestSolution.begin(),bestSolution.end() ); for( int i=0; i<(int)bestSolution.size(); i++) cout << bestSolution[i] << " "; cout <<"\nTime used "<< (clock()-begin)/1000.0 << "s" <<endl; } return 0; }
相关文章推荐
- 硬币组合问题-动态规划
- 硬币组合问题
- 动态规划-最少硬币组合问题
- 一维数组和二维数组求解硬币组合个数问题
- 硬币组合问题
- hdu1085(母函数解有限个硬币组合问题)
- 关于硬币组合问题和DP的结合
- LeetCode 77. Combinations 组合问题C(n,k),树形状态回溯,优化减枝
- 动态规划应用—硬币组合问题
- 回溯题目/排列、组合、子集问题
- UVA147硬币组合问题,double型和int型的输出格式,以及double型本身存在的精度问题
- 回溯算法之 幂集问题(组合问题)
- Leetcode22.+Leetcode216. 回溯法之应用(二):圆括号+组合问题
- Recursion 硬币组合问题 @CareerCup
- Subsets and Subsets II (回溯,DFS,组合问题)
- 硬币组合问题之最少硬币个数
- 程序员面试金典(动态规划):1分,5分,10分,25分硬币面值组合问题(解题思路)
- 硬币面值组合问题
- 硬币组合问题
- 【编程之法】硬币面值组合问题