ACM —— 1010 STAMPS
2015-09-11 13:15
405 查看
解题代码:
DFS + 剪枝
关键在剪枝
最多拿四张邮票,同面额的邮票种类超过5,则按5计算
顾客持有邮票张数不超过4
不重复搜索比当前面值小的邮票,同时避免错误的tie(i=pre)
减掉比当前面值大的邮票,排序的好处
小技巧:种类 > 张数 > 最大面值
评价分数 = 种类数 * 100 + (4 - 邮票数) * 10 + 最大面值;
import java.util.Arrays; import java.util.Scanner; public class Main { private static int[] mValues; private static int[] mTime; private static int[] mSolve; private static int[] mBestSolve;//solve[4]:邮票张数 solve[5]:邮票种数 solve[0..3]:持有的邮票面值,0表示不持有 private static int tempScore; private static boolean flagTie; public static void main(String[] args) { Scanner stdin = new Scanner(System.in); while (stdin.hasNextLine()) { int[] values = new int[100]; int[] type = new int[26]; int length = 0; int temp; int count = 0; int cusRequests; while ((temp = stdin.nextInt()) != 0) { if (type[temp] < 5) { //剪枝,同面额的邮票种类超过5,则按5计算 type[temp]++; values[length++] = temp; } } while ((cusRequests = stdin.nextInt()) != 0) { getBestByDFS(cusRequests, values,length); outBestSolve(cusRequests); } } } private static void getBestByDFS(int cusRequests, int[] values, int length) { init(values,length); dfs(cusRequests, 0, 0, 0); } private static void init(int[] values, int length) { mValues = new int[length]; mTime = new int[length]; mSolve = new int[5]; mBestSolve = new int[6]; tempScore = 0; flagTie = false; System.arraycopy(values, 0, mValues, 0, length); Arrays.sort(mValues); } private static void outBestSolve(int cusRequests) { if (mBestSolve[4] == 0) { System.out.println(cusRequests + " ---- none"); } else if (flagTie) { System.out.println(cusRequests + " (" + mBestSolve[5] + "): tie"); } else { System.out.print(cusRequests + " (" + mBestSolve[5] + "):"); for(int i = 0; i < 4; i++) { if (mBestSolve[i] == 0) { break; } System.out.print(" " + mBestSolve[i]); } System.out.println(); } } /** * * @param need 总面值 * @param num 邮票张数 * @param type 邮票种数 * @param pre 剪枝 * @return */ private static void dfs(int need, int num, int type, int pre) { if (num == 5) { //剪枝,顾客持有邮票张数不超过4 return; } if (need == 0) { int score = type*100 + (4 - num)*10 + getMax(); if (score == tempScore) { flagTie = true; } else if (score > tempScore){ flagTie = false; tempScore = score; mBestSolve[4] = num; mBestSolve[5] = type; for (int i = 0; i < 4; i++) { mBestSolve[i] = mSolve[i]; } } return; } for (int i = pre; i < mValues.length; i++) { //i=pre 剪枝,不重复搜索比当前面值小的邮票,同时避免错误的tie if (need < mValues[i]) {//剪枝, 减掉比当前面值大的邮票,排序的好处 return; } mSolve[num++] = mValues[i]; if (mTime[i] != 0) { mTime[i]++; dfs((need - mValues[i]), num, type, i); } else { mTime[i]++; dfs((need - mValues[i]), num, type+1, i); } mSolve[--num]=0; //回溯 mTime[i]--; } return ; } private static int getMax() { int a = mSolve[1] > mSolve[2] ? mSolve[1]:mSolve[2]; int b = mSolve[3] > mSolve[4] ? mSolve[3]:mSolve[4]; return (a > b ? a:b); } }
DFS + 剪枝
关键在剪枝
最多拿四张邮票,同面额的邮票种类超过5,则按5计算
顾客持有邮票张数不超过4
不重复搜索比当前面值小的邮票,同时避免错误的tie(i=pre)
减掉比当前面值大的邮票,排序的好处
小技巧:种类 > 张数 > 最大面值
评价分数 = 种类数 * 100 + (4 - 邮票数) * 10 + 最大面值;
相关文章推荐
- PHP的输出缓冲区(转)
- LDA 主题模型的几种概率分布
- IOS打开照相机与本地相册选择图片
- 《剑指offer》树的子结构
- 最近的一些事儿
- 【项目2 - 程序的多文件组织】 ---xjp
- 字符串和编码
- 字符串匹配的Boyer-Moore算法
- IOS使用UIImageView显示gif动画的例子
- IOS使用UIImageView显示gif动画的例子
- Zabbix---添加linux服务器监控
- xmpp Smack asmack Spark MINA Openfire androidpn MQTT RSMB
- KMP算法详解
- 微信第三方平台开发三(消息加解密)
- ubuntu中安装gcc和g++编译环境
- Android开发_View 硬件加速
- Redhat 6.4-x64 编译 Hadoop-2.7.1并分布式安装
- 小菜的前端编程散谈(1)
- PowerDesigner概述(系统分析与建模)以及如何用PowerDesigner快速的创建出这个数据库
- libcurl库基本使用