北大OJ_1010题:STAMPS

2023-10-24 10:18
文章标签 北大 oj 1010 stamps

本文主要是介绍北大OJ_1010题:STAMPS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;typedef vector<int> IntArray;#define		MAX_STAMP_N				4		//最大邮票数
#define		MAX_TYPE_N				25		//最大邮票种类数25struct tagResultHelper
{int nCurTypeCount;				//当前种类数int nCurStampCount;				//当前邮票数int nCurMaxValue;				//当前最大面额int mResultSets[MAX_STAMP_N];	//当前结果集(始终保存最优的结果集)bool bTieFlag;					//tie标记
};tagResultHelper gResultHelper;	//结果集合辅助变量
int gStampArray[MAX_TYPE_N];	//邮票种类数组(保存每种面值)
int gTotalTypeCount;			//总的邮票种类数//得到最大值
int GetMaxValue( int mIntArray[MAX_STAMP_N], int nCurCount )
{int nMax = -1;for( int i = 0; i < nCurCount; ++i ){if ( mIntArray[i] > nMax ){nMax = mIntArray[i];}}return nMax;
}//更新最优解
void UpdateBestResult( int nCurTypeCount, int nCurMaxValue, int nCurStampCount,int mIntArray[MAX_STAMP_N] )
{//种类多于当前的,加入if ( nCurTypeCount > gResultHelper.nCurTypeCount ){gResultHelper.nCurTypeCount = nCurTypeCount;gResultHelper.nCurStampCount = nCurStampCount;gResultHelper.nCurMaxValue = nCurMaxValue;//更新结果gResultHelper.bTieFlag = false;//重置tie标记for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];}//种类等于当前的else if ( nCurTypeCount == gResultHelper.nCurTypeCount ){//邮票数目小于当前的if( nCurStampCount < gResultHelper.nCurStampCount ){gResultHelper.nCurTypeCount = nCurTypeCount;gResultHelper.nCurStampCount = nCurStampCount;gResultHelper.nCurMaxValue = nCurMaxValue;//更新结果gResultHelper.bTieFlag = false;//重置tie标记for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];}//邮票数目等于当前的else if ( nCurStampCount == gResultHelper.nCurStampCount ){//单张面值最大的大于当前的if ( nCurMaxValue > gResultHelper.nCurMaxValue ){gResultHelper.nCurTypeCount = nCurTypeCount;gResultHelper.nCurStampCount = nCurStampCount;gResultHelper.nCurMaxValue = nCurMaxValue;//更新结果gResultHelper.bTieFlag = false;//重置tie标记for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];}//单张面值最大的等于当前的else if ( nCurMaxValue == gResultHelper.nCurMaxValue ){if ( !gResultHelper.bTieFlag ){for( int i = 0; i < nCurStampCount; ++i ) gResultHelper.mResultSets[i]=mIntArray[i];gResultHelper.bTieFlag = true;//已经tie了}}}}
}void GetResult_DFS( int mDstArrayTemp[], int& nCurStampCount, int& nCurTypeCount, int nTarget, int iStart )
{if ( nTarget < 0 ) return;if ( nTarget == 0 ){//找到一组结果UpdateBestResult( nCurTypeCount, GetMaxValue( mDstArrayTemp, nCurStampCount ), nCurStampCount, mDstArrayTemp );}else{for( int i = iStart; i < gTotalTypeCount; ++i ){//后面更大的数不可能满足条件或者邮票数已经是4张,不能容纳更多了(剪枝操作)if( gStampArray[i] > nTarget || nCurStampCount >= 4 ) break;//种类数递增if ( i > iStart || nCurStampCount <= 0 ){++nCurTypeCount;}mDstArrayTemp[nCurStampCount++] = gStampArray[i];//因为可以重复使用,所以可继续从当前位置递归GetResult_DFS( mDstArrayTemp, nCurStampCount, nCurTypeCount, nTarget-gStampArray[i], i );//重置,即回溯操作if ( i > iStart || nCurStampCount == 1 ){--nCurTypeCount;}nCurStampCount--;}}
}//回溯法
int main()
{IntArray customerVec;while ( true ){int nTemp = 0;int type[MAX_TYPE_N] = {0};  //面值为i的邮票的种数type[i] gTotalTypeCount = 0;//while( cin >> nTemp )while( true ){if ( scanf("%d", &nTemp ) == EOF ) exit(0);if ( 0 == nTemp || gTotalTypeCount == MAX_TYPE_N ) break;//gStampArray[gTotalTypeCount++] = nTemp;if( type[nTemp-1] < 5 )     //剪枝,同面额的邮票种类超过5,则按5计算  {  type[nTemp-1]++;  gStampArray[gTotalTypeCount++] = nTemp;}}sort( gStampArray, gStampArray+gTotalTypeCount );customerVec.clear();while( cin >> nTemp ){if ( 0 == nTemp ) break;customerVec.push_back( nTemp );}for( int i = 0; i < customerVec.size(); ++i ){int iCurTypeCount = 0;int iCurStampCount = 0;int mDstVecTemp[MAX_STAMP_N];memset( mDstVecTemp, 0, sizeof(mDstVecTemp) );gResultHelper.nCurMaxValue = 0;gResultHelper.nCurStampCount = 0;gResultHelper.nCurTypeCount = 0;gResultHelper.bTieFlag = false;memset( gResultHelper.mResultSets, 0, sizeof(gResultHelper.mResultSets) );GetResult_DFS( mDstVecTemp, iCurStampCount, iCurTypeCount, customerVec[i], 0 );if ( gResultHelper.nCurTypeCount <= 0 ){cout << customerVec[i] << " ---- none" << endl;}else if ( gResultHelper.bTieFlag ){cout << customerVec[i] << " (" << gResultHelper.nCurTypeCount << "): tie" << endl;}else{cout << customerVec[i] << " (" << gResultHelper.nCurTypeCount << "):";for( int k = 0; k < gResultHelper.nCurStampCount; ++k ){cout << " " << gResultHelper.mResultSets[k];}cout << endl;}}}return 0;
}



参考文章:http://blog.csdn.net/lyy289065406/article/details/6647948



作者:山丘儿
转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46726249


这篇关于北大OJ_1010题:STAMPS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/274473

相关文章

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

165-Stamps【回溯】

回溯 给h和k的意思是在k种邮票中选h个邮票 基本的连续邮资问题 15226160 165 Stamps Accepted C++ 0.062 2015-03-27 07:21:37 #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 2

哈理工OJ 2179(深搜)

组合 Time Limit: 1000 MSMemory Limit: 32768 K Total Submit: 7(5 users)Total Accepted: 6(5 users)Rating: Special Judge: No Description 给出一个正整数N,从集合{1,2,3..N} 中找出所有大小为k的子集, 并按照字典序从小到大输出。 Input 第一行是一个整

每日OJ_牛客_求和(递归深搜)

目录 牛客_求和(递归深搜) 解析代码 牛客_求和(递归深搜) 求和_好未来笔试题_牛客网 解析代码         递归中每次累加一个新的数,如果累加和大于等于目标,结束递归。此时如果累加和正好等于目标,则打印组合。向上回退搜索其它组合。此题本身就是一个搜索的过程,找到所有的组合。 #include <iostream>#include <cmath>#in

HDU 1010 Tempter of the Bone (搜索)

OJ题目 : click here ~~ 大概题意 : 迷宫搜索。从起点到终点 ,不能回头 , 问能不能在恰好在T 时刻,准时到达终点。 本题充分体现了剪枝的重要性: 奇偶性剪枝: 可以把maze看成这样:  0 1 0 1 0 1  1 0 1 0 1 0  0 1 0 1 0 1  1 0 1 0 1 0  0 1 0 1 0 1  从为 0 的格子走一步,必然走向为 1 的格子

OJ-0905

题目 示例1: 输入:10 10 56 34 99 1 87 8 99 3 255 6 99 5 255 4 99 7 255 2 99 9 255 213 4输出:99 示例2: 输入:10 10 255 34 0 1 255 8 0 3 255 6 0 5 255 4 0 7 255 2 0 9 255 213 5输出:255 import java.util.

每日OJ_牛客_Emacs计算器(逆波兰表达式)

目录 牛客_Emacs计算器(逆波兰表达式) 解析代码 牛客_Emacs计算器(逆波兰表达式) Emacs计算器__牛客网 解析代码 逆波兰表达式(后缀表达式)求值,需要借助栈,思路: 循环输入,获取逆波兰表达式,然后进行以下补助,直到测试完所有的测试用例: 遇到数字字符串,将该数字字符串转化为数字然后入栈。遇到操作符时,从栈顶取两个数字,然后进行该运算符所对应运算

西北工业大学oj题-兔子生崽

题目描述: 兔子生崽问题。假设一对小兔的成熟期是一个月,即一个月可长成成兔,每对成兔每个月可以生一对小兔,一对新生的小兔从第二个月起就开始生兔子,试问从一对兔子开始繁殖,一年以后可有多少对兔子? 这道题目一眼看过去就是典型的递归问题,代码如下 public class RabbitReproduction {public static void main(String[] args) {in

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑极端事件的电力系统惯量与一次调频备用联合规划配置方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

★ 算法OJ题 ★ 力扣209 - 长度最小的子数组

Ciallo~(∠・ω< )⌒☆ ~ 今天,简将和大家一起做一道滑动窗口算法题--长度最小的子数组~ 目录 一  题目 二  算法解析 解法⼀:暴力求解 解法二:滑动窗口 三  编写算法 一  题目 209. 长度最小的子数组 - 力扣(LeetCode) 二  算法解析 解法⼀:暴力求解 算法思路: 从前往后枚举数组中的任意⼀个元素,把它当成起始位置