http://www.cnblogs.com/hansongjiang/p/3810825.html上篇文章我考虑的是可以找零的方式有几种,是运用搜索解决的,但是如果我们要解决的是优化问题,就是说最小要多少硬币呢?
题目的地址是:http://acm.nyist.net/JudgeOnline/problem.php?pid=995其实他是一个背包问题,所以我准备重学一下。
最近做硬币找零问题,它实际是个背包问题,很多知识掌握的不扎实。
这里重新总结一下,老规矩,还是靠题目驱动,下面所有题目都给了链接
参考了:
http://www.cnblogs.com/jiangjun/archive/2012/05/08/2489590.html
题目链接:就为了这个题目,我注册个
http://acm.swust.edu.cn/oj/problem/32/大家可以提交一下试试。
设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,…wn。
问能否从这n件物品中选择若干件放入背包中,使得放入的重量之和正好为S。
如果有满足条件的选择,则此背包有解,否则此背包问题无解。
例如 20 能不能有 1 3 5 7 9 组成,我们很容易判断是 1 3 7 9组成 20,所以回答 yes
10: 12 3 4 不可以组成10,回答No
首先从搜索的角度来看,一个集合有 n个元素,共有 2的n次方可能性,这类问题都可以
通过搜索解决,因为每个元素只有存在集合或者不存在集合当中。
例如{1,4} 共有 4种可能,1 ,4, 1和4 枚举所有可能就可以,搜索的时候当然很多都是不符合答案的,要学会剪枝;
然后就很容易转化为代码
fun(W,S ) W: 当前的还剩下的重量 S:当前还剩下的物品的物品,fun返回true或者false;表示可否组成。
对于第S个物品,选择 变成 fun(W-w[S],S-1)不选,fun(W,S-1)
fun(W,S)=fun(W-w[S],S-1)||fun(W,S-1);
#include <iostream> using namespace std; const int N=1005; int w[N]; bool fun(int W,int S) { if(W==0) return true; //剩下钱为0,则返回true; if(W<0) return false; if(W>0&&S==0) return false; //剩下钱大于0,但是没有物品可选,就是失败 return fun(W-w[S],S-1)||fun(W,S-1); } int main() { int W,S; while(cin>>W>>S) { for(int i=1;i<S+1;i++) { cin>>w[i]; } if(fun(W,S)) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } } system("pause"); return 0; }