POJ 1010 STAMPS
来源:互联网 发布:寒门崛起抄袭软件 编辑:程序博客网 时间:2024/05/18 02:20
又是一道经典搜索题,剪枝是必须的!
题意有点晦涩,参考了网上提供的中文版才明白过来到底是个什么事。
具体题意可参考http://blog.csdn.net/sdj222555/article/details/7240991这篇博文,同时也给出了用经典DFS模板写的代码。
这里给出了个人所想的剪枝方法:
1. 重点剪枝:由于题目中说明了不同类型的邮票可能具有相同的面值,所以这里把首先把邮票按面值大小进行排序,然后只保留面值不同的邮票,以及邮票面值相同时的邮票种类数。搜索组合方案时,暂时只考虑面值大小,不考虑邮票种类。
如邮票种类:1 1 1 1 2 2 2 3 3 就可以表示为:(1, 4), (2, 3), (3, 2);
要求找到面值总额为5的组合,那么搜索会考虑到这个组合:面值为1的需要3张,面值2的需要1张。事实上,面值1的邮票种类数有4张,为了使得最后的邮票种类数达到最大,应该使得组合中的3张面值为1的邮票种类不同。
2. 所需的面值总额小于最小的邮票面值时,停止
3. 邮票张数超过4,时,停止
这三个剪枝中,2,3是应题目要求,只有1是需要自己拿脑子来想想的。
附代码:
#include <iostream>#include <vector>#include <algorithm>using namespace std;class Answer{ public:int types;int number;int maxValue;vector<pair<int,int> > ans;Answer(int t=0, int n=0, int m=0):types(t), number(n), maxValue(m){};void assign(const vector<pair<int,int> >& temp, const vector<pair<int,int> >& stamps){ int i = 0; while( temp[i].second && i < temp.size() ) {int j = temp[i].first;types += min(stamps[j].second, temp[i].second);number += temp[i].second;ans.push_back(pair<int, int>(j, temp[i].second));++i; } maxValue = stamps[ans.back().first].first;}int replace(const Answer& temp){ if(temp.types == types && temp.number == number && temp.maxValue == maxValue)return 0; if(types > temp.types)return 1; else if(types < temp.types) {*this = temp;return -1; } if(number < temp.number)return 1; else if(number > temp.number) {*this = temp;return -1; } if(maxValue > temp.maxValue)return 1; else if(maxValue < temp.maxValue) {*this = temp;return -1; }}void clear(){ types = number = maxValue = 0; ans.clear();}};vector<pair<int, int> > stamps;Answer answer;vector<pair<int, int> > temp_ans;bool first, tie;void Work(int level, int pos, int need, int num){ if( !need ) {/*cout << "--------------------" << endl;for(int i = 0; i < temp_ans.size(); ++i){ int j = temp_ans[i].first; cout << stamps[j].first << " " << temp_ans[i].second << endl;}cout << "--------------------" << endl;*///a solutionif( first ){ first = false; answer.assign(temp_ans, stamps);}else { Answer temp ; temp.assign(temp_ans, stamps); int r = answer.replace( temp ); if( !r )tie = true; else if(tie && r == -1)tie = false;}return ; } if(num <= 0 || pos >= stamps.size() || level >= 4)return ; if(need < stamps[pos].first)return; int n = min(need/stamps[pos].first, num); for(int i = 0; i <= n; ++i) {int j = i>0?1:0;temp_ans[level] = pair<int,int>(pos, i);Work(level+j, pos+1, need-stamps[pos].first*i, num-i);temp_ans[level] = pair<int,int>(0, 0); }}void Preprocess(vector<int>& v){ sort(v.begin(), v.end()); stamps.clear(); stamps.push_back( pair<int, int>(v[0], 1) ); int k = 0; for(int i = 1; i < v.size(); ++i) {if(stamps[k].first != v[i]){ stamps.push_back( pair<int,int>(v[i], 1) ); ++k;}else stamps[k].second += 1; }}void JudgeTie(){ vector<pair<int,int> > v = answer.ans; for(int i = 0; i < v.size(); ++i) {int pos = v[i].first, num = v[i].second;int types = stamps[pos].second;if(types > 1 && num != types){ tie = true; break;} }}int main(){ int stamp; while( cin >> stamp ) {vector<int> v;while( stamp ){ v.push_back( stamp ); cin >> stamp;}Preprocess( v );int minDemand = v.front();int maxDemand = v.back()*4;int demand;while( cin >> demand && demand ){ if( demand < minDemand || demand > maxDemand ) {cout << demand << " ---- none" << endl;continue; } first = true; tie = false; temp_ans.assign(4, pair<int,int>(0, 0)); answer.clear(); Work(0, 0, demand, 4); if( first ) {cout << demand << " ---- none" << endl;continue; } JudgeTie(); if( tie ) {cout << demand << " (" << answer.types << "): tie" << endl;continue; } cout << demand << " (" << answer.types << "):"; vector<pair<int, int> > v = answer.ans; for(int i = 0; i < v.size(); ++i) {for(int k = 0; k < v[i].second; ++k) cout << " " << stamps[v[i].first].first; } cout << endl;} } return 0;}
- POJ 1010 STAMPS
- poj 1010 STAMPS
- poj 1010 STAMPS
- POJ-1010-STAMPS
- [POJ][1010]STAMPS
- POJ 1010 STAMPS
- POJ - 1010 STAMPS
- POJ 1010: STAMPS
- POJ 1010 STAMPS(DFS)
- POJ 1010 STAMPS
- POJ 1010--STAMPS
- STAMPS POJ 1010
- poj 1010:STAMPS
- POJ 1010 STAMPS 笔记
- POJ 1010--STAMPS
- POJ 1010 解题报告 STAMPS
- POJ 1010 STAMPS 解题报告
- UESTC 408 STAMPS // poj 1010
- Linux下运行sh文件“permission denied”问题解决方案
- 屌丝码农入住csdn
- android反编译工具总结
- c++ 运算符的重载
- VC制作托盘(转)
- POJ 1010 STAMPS
- 音视频转码器产品规格
- Java web中的mvc模式
- vim多窗口使用技巧
- 静态 类数据成员、const与类
- 从Nand flash启动的uboot
- 在Silverlight应用程序中前段JavaScript与后台C#之间的交互
- VC实现托盘程序(转)
- struts2实现文件下载