- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
假设某国家发行了n种不同面值的邮票并且规定每张信封上最多只允许贴m张.连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计,使得可在1张信封上贴出从邮资1开始,增量为1的最大连续邮资区间.例如:当n=5,m=4时,面值为(1,3,11,15,32)的五种邮票可以贴出邮资的最大连续邮资区间是1到70.
当时选拔赛我就这道题没做上,现在还是不会,请高手指点.听说要用回朔法,不过我还是不会.请把算法说清楚.
这个题就是搜啊搜啊,剪啊剪啊:)呵呵~~~~不过俺这方面不强,以前做的程序也不够快,这个题海星大哥发给过我他做的东西,虽然我还留着,不过就让海星大哥贴他的解析吧:)不过我看这好象刘汝佳没来(他喜欢ID就用自己名),而我也见过他站上写的这个东西的解析,贴出来看看吧:)
*****************************
第四题 邮票面值设计(40分)
给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+k=40) 种邮票的情况
下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大max ,使得1-
max之间的每一个邮资值都能得到。
例如,N=3,K=2,如果面值分别为1分、4分,则在l分-6分之间的每一个邮资值
都能得到(当然还有8分、9分和12分):如果面值分别为1分、3分,则在1分-7分之间的
每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到连续的邮资最大值
,所以MAX=7,面值分别为l分、3分。
样例:
INPUT
N=3 k=2
OUTPUT
1 3
MAX=7
不知同学们第一个感觉是不是递推?反正我当时是。我想了一会儿,发现递推是行不通的,
然后一个很自然的思路就是搜索。当时我很不想用搜索,因为上限是K=40,N=40,但后来才知道
这是出题者的一个疏忽,根本不可能在时限内到40的。从下面的测试数据中也可以看出来。
解状态是一个K元组(v1,v2,v3..vk),不妨设:v1v[p],而若v[p]=R+2,
则R+1根本不可能取到。
递归搜索就可以了。
本题的难点是如何计算最大连续值(以下成为Q值)。
一个容易想到的方法是枚举所有的取法,求出可以取到的最大值,再求Q值,简单,但是效率不高。
以下是供参考的递推其他方法:
递推求Q值,保存前P个面值用1,2,3..K张可以取得的值,再加上第P+1张取与不取的情况可以得到前P+1个面值
用1,2,3..K张可以取得的值。即,用T张前P个面值能得到S,用T+1张前P+1个面值可以得到S+V[P+1],用T张前
P+1个面值也能得到S.
为了使程序易懂,我采用的是简单的方法,效率低一些,但是好懂一些。以下我竞赛时写的程序,后来加了
很多注释,将就看一下吧!
我先把可能不好懂的地方说一下:
1.Cont(x)就是前x个元素的Q值
2.Find(Findstart,Contstart,x); x:当前搜索的邮票序号,findstart:第x张邮票的最小可能值(搜索起点),
Contstart:需要从Contstart开始连续取值(也就是:前x-1张可以从1取到Contstart-1)
OK,Here it is:
{$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,R-,S-,V+,X-}
{$M 65520,0,655360}
Program Stamp;
Const
Maxn=40;
Var
Value,BestValue : Array[1..Maxn] Of Integer;
Max,N,K : Integer;
{If N=5,K=5 Value[]=(1,4,9,31,51), It returns 126, Got it?}
Function Cont(x:Integer):Integer;
Var
I:Integer;
CanGet:Array[0..10000] Of Boolean;
Count:Array[1..Maxn] Of Integer;
Procedure UseIt(Num,Left:Integer);
Var
I:Integer;
Total:Integer;
Begin
If Num=x+1 Then
Begin
Total:=0;
For I:=1 to x Do Inc(Total,Value[i]*Count[I]);
CanGet[Total]:=True;
Exit;
End;
For I:=0 to Left Do
Begin
Count[N
原创力文档


文档评论(0)