pku acm 1010
2011-10-08 21:24
204 查看
参考了http://blog.csdn.net/huxin2007/article/details/6766074的文章。
类似于究举法。
主要思路:
1. 先对输入按面值的从小到大排序,这对剪枝有帮助,比如:
输入面值:1,2,3,4,5 顾客要求是 3
假如计算到分支 1,1,2 的时候,超过 3 了,后面的 1,1,3 ; 1,1,4 ; 1,1,5 都不需要计算了
2. 对解的评价,采用了一个计算公式,省去了较复杂的条件判断。--这个比较好
评价分数 = 种类数 * 100 + (4 - 邮票数) * 10 + 最大面值;
类似于究举法。
主要思路:
1. 先对输入按面值的从小到大排序,这对剪枝有帮助,比如:
输入面值:1,2,3,4,5 顾客要求是 3
假如计算到分支 1,1,2 的时候,超过 3 了,后面的 1,1,3 ; 1,1,4 ; 1,1,5 都不需要计算了
2. 对解的评价,采用了一个计算公式,省去了较复杂的条件判断。--这个比较好
评价分数 = 种类数 * 100 + (4 - 邮票数) * 10 + 最大面值;
#include <iostream> #include <algorithm> using namespace std; int stamps[100]; //存放邮票的种类(取25在poj上不能通过,在zoj上可以通过) int denomination; //顾客要求的面值 int nTypes; //邮票种类数 int result[4]; //存放最终结果 int mresult[4]; //存放中间结果 bool tie = false; //判断是否有tie int score = 0; //最优解的分数 int cards = 0; //最优解中有多少张邮票 int kindsnum = 0; //最优解中有多少种邮票 int kinds[4]; //记录类型的数组 void DFS(int sum, int index, int ccards/*当前解中有多少张邮票*/) { if((ccards > 3) && (sum != denomination)) return; //失败了,剪枝 if(sum == denomination)//成功了,开始评分 { int ckindsnum = 1;//当前解中有多少种邮票 for(int i = 1; i < ccards; i++) { if(kinds[i] != kinds[i-1]) ckindsnum++; } int cscore = ckindsnum * 100 + (4 - ccards) * 10 + stamps[index];//当前解的评分 if(cscore == score) tie = true; else if(cscore > score) { tie = false; score = cscore; cards = ccards; kindsnum = ckindsnum; for(int i = 0; i < 4; i++) result[i] = mresult[i]; } return; } for(int i = index; i < nTypes; ++i) { if(sum + stamps[i] > denomination)return;//剪枝 mresult[ccards] = stamps[i]; kinds[ccards] = i; DFS(sum + stamps[i], i, ccards + 1); } return; } void Print() { if (score == 0) { cout << denomination << " ---- none" << endl; return; } if(tie) { cout << denomination << " (" << kindsnum << "): tie" << endl; return; } else { cout << denomination << " (" << kindsnum << "): "; for(int i = 0; i < cards; i++) cout << result[i] << " "; } cout << endl; } int main() { freopen("in.txt", "rt", stdin); //从0开始计数 nTypes = 0; while(cin>>stamps[nTypes]) { for (++nTypes; cin>>stamps[nTypes] && stamps[nTypes] != 0; ++nTypes); sort(stamps,stamps+nTypes); while(cin>>denomination && denomination != 0) { score = 0,tie = false; DFS(0,0,0); Print(); } nTypes = 0; } return 0; }
相关文章推荐
- 1010(stamps),acm.pku.edu.cn
- acm--pku--1458
- pku acm题目分类 (1)
- http://acm.hdu.edu.cn/showproblem.php?pid=1010
- PKU-ACM-题型分类的代码
- Pku acm 1179 Polygon 动态规划题目解题报告(二十)
- Pku acm 2159 Ancient Cipher 排序算法解题报告(六)----计数排序
- 杭电ACM1010——深度优先搜索+奇偶剪枝
- ACM HDOJ 1010 (Tempter of the Bone)
- ACM PKU 1048 Follow My Logic
- Pku acm 1050 To the Max 【动态规划】
- PKU ACM 1007题“DNA Sorting”的一种解法
- ACM PKU 1011 Sticks 深度优先搜索
- acm之pku题目分类[ZT]
- http://acm.pku.edu.cn/JudgeOnline/problem?id=3468 成段更新,区间求和(要用long long)
- http://acm.pku.edu.cn/JudgeOnline/problem?id=3667 区间更新+求满足长短的最左区间
- PKU 1258 POJ 1258Agri-Net ( MST Kruskarl 并查集 ) ACM 1258 IN PKU
- ACM PKU POJ 1740 解题报告 -- 男人八题之四
- pku1727 Advanced Causal Measurements (ACM) .
- pku acm 1002