NOIP2006提高组满分源代码
NOIP2006提高组复赛解题报告
1、DP,f表示合并区间内的珠子获得最大能源2、DP,可以先把主件和附件的搭配全部分出来,然后分阶段做背包3、模拟4、递推+高精度1.这题具有最优子结构的性质,与合并石子相似,所以可以用动态规划来做。
首先将数据存于c数组中,每次需要枚举一下起始点i和终点j的位置,还要枚举起点和终点之间一个断点k的位置,表示第i—k个珠子已经合并在了一起,第k—j个珠子也已经合并在了一起,当前要合并的是这两个已经合并在了一起的小珠子,这样就把一个问题分成了许多子问题。
当前一次操作所产生的能量K=c[i]*c[k]*c[j]具体做法是:开一个二维数组a,a[i,j]表示从i开始到j结束这一段中所有珠子合并所能产生的能量的最大值。
然后先枚举段的长度i(i为2到N),接着枚举开始位置j,由i, j 可推出结束位置k。
然后枚举断点位置v,v为j+1到k-1之间。
在每个断点处断开所能获得的能量为K=c[j]*c[v]*c[k]+a[j,v]+a[v,k]。
取这中间的一个最大值赋给a[j , k]。
这样做的时间复杂度为O(n3),因为N<=100,所以时间上肯定没有问题。
最后a[i,i]的最大值就是合并所有珠子后所能产生的能量的最大值。
constmaxn=100;varc:array[0..maxn] of longint;a:array[0..maxn,0..maxn] of longint;n,i,j,k,t,v,u,max:longint;beginassign(input,'energy.in'); reset(input);assign(output,'energy.out'); rewrite(output);readln(n);for i:=0 to n-1 do read(c[i]);fillchar(a,sizeof(a),0);for i:=2 to n do beginfor j:=0 to n-1 do begink:=(j+i) mod n;max:=0;for v:=j+1 to j+i-1 do beginu:=v mod n;t:=c[j]*c[u]*c[k]+a[j,u]+a[u,k];if t>max then max:=t;end;a[j,k]:=max;end;end;max:=0;for i:=0 to n-1 doif a[i,i]>max then max:=a[i,i];writeln(max);close(input); close(output)end.2、此题初看MS是01背包问题,只是多了附件这个条件。
2006年青少年信息学奥林匹克小学组复赛试题
2006年青少年信息学奥林匹克小学组复赛比赛时间3小时满分200分共4题注意事项:每道题目均有5组测试数据,每组测试数据均为10分,测试数据的范围均在题目中给出了描述。
每道题目都是文件输入、文件输出,屏幕的输入和输出无效。
题目的测试文件为xxx.in文件,请选手们注意,5组测试数据均放在同一个输入文件中,也就是你应该在你的程序最外层套一个循环,从而执行程序主体5次,对于每次运行程序主体,直接把本次结果输出到要求输出的xxx.out文件中,以方便评委的评测工作。
题目中一个样例就是对于一组数据的描述。
例如:给定两个整数a和b,求他们的和。
(假如输入文件文件:a.in , 输出文件:a.out)DIM a AS INTEGER, b AS INTEGERDIM casenum AS INTEGEROPEN "a.in" FOR INPUT AS #1OPEN "a.out" FOR OUTPUT AS #2FOR casenum = 1 TO 5 [ 注意此处循环了5次主体程序,就是为了解决5组数据] INPUT #1, a, b [ 程序主体]WRITE #2, a + b [ 程序主体]NEXT casenumCLOSE #1, #2上面的程序可以作为今天比赛的模板,[程序主体]部分可以替换为每道题目的具体代码。
提醒参赛选手,对于[程序主体]的开头要注意清空上一次循环存留下来的无用数据,以免造成这次运算的错误。
偶数世界源代码: even.bas输入文件: even.in输出文件: even.out假想我们生活在偶数世界里,在这个世界中只有正偶数。
下面就是这个世界中数的集合:Z = {2, 4, 6, 8, 10 ……};在偶数世界中,除法有它特殊的规则,如果数a能被数b整除,那么a除以b的商也一定是个偶数。
例如2能整除8, 因为2 * 4 = 8。
但是2却不能整除6,因为2 * 3 = 6。
少儿编程NOIP2009提高组复赛试题
全国信息学奥林匹克联赛(NOIP2009)复赛提高组(请选手务必仔细阅读本页内容)注意事项:1、文件名(程序名和输入输出文件名)必须使用小写。
2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。
3、全国统一评测时采用的机器配置为:CPU 1.9GHz,内存1G,上述时限以此配置为准。
各省在自测时可根据具体配置调整时限。
1.潜伏者(spy.pas/c/cpp)【问题描述】R 国和S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动。
历尽艰险后,潜伏于S 国的R 国间谍小C 终于摸清了S 国军用密码的编码规则:1.S 国军方内部欲发送的原信息经过加密后在网络上发送,原信息的内容与加密后所得的内容均由大写字母‘A’-‘Z’构成(无空格等其他字符)。
2.S 国对于每个字母规定了对应的“密字”。
加密的过程就是将原信息中的所有字母替换为其对应的“密字”。
3.每个字母只对应一个唯一的“密字”,不同的字母对应不同的“密字”。
“密字”可以和原字母相同。
例如,若规定‘A’的密字为‘A’,‘B’的密字为‘C’(其他字母及密字略),则原信息“ABA”被加密为“ACA”。
现在,小C 通过内线掌握了S 国网络上发送的一条加密信息及其对应的原信息。
小C 希望能通过这条信息,破译S 国的军用密码。
小C 的破译过程是这样的:扫描原信息,对于原信息中的字母x(代表任一大写字母),找到其在加密信息中的对应大写字母y,并认为在密码里y 是x 的密字。
如此进行下去直到停止于如下的某个状态:1.所有信息扫描完毕,‘A’-‘Z’ 所有26 个字母在原信息中均出现过并获得了相应的“密字”。
2.所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出现。
3.扫描中发现掌握的信息里有明显的自相矛盾或错误(违反S 国密码的编码规则)。
例如某条信息“XYZ”被翻译为“ABA”就违反了“不同字母对应不同密字”的规则。
少儿编程NOIP2006提高组复赛试题
NOIP 2006 复赛试题 (提高组)第十二届全国青少年信息学奥林匹克联赛复赛试题(NOIP2006 提高组)竞赛时间:2006 年11 月18 日上午8:30—11:30关于竞赛中不同语言使用限制的说明一.关于使用Pascal 语言与编译结果的说明1.对于Pascal 语言的程序,当使用IDE 和fpc 编译结果不一致时,以fpc 的编译结果为准。
2.允许使用数学库(uses math 子句),以及ansistring。
但不允许使用编译开关(最后测试时pascal的范围检查开关默认关闭:{$R-,Q-,S-}),也不支持与优化相关的选项。
二.关于C++语言中模板使用的限制说明1.允许使用的部分:标准容器中的布尔集合,迭代器,串,流。
相关的头文件:<bitset > <iterator > <string > <iostream >2.禁止使用的部分:序列:vector,list,deque序列适配器:stack, queue, priority_queue关联容器:map, multimap, set, multiset拟容器:valarray散列容器:hash_map, hash_set, hash_multimap, hash_multiset所有的标准库算法相关头文件:<vector > <list > <deque > <stack > <map > <set > <algorithm >1.能量项链(energy.pas/c/cpp)【问题描述】在Mars 星球上,每个Mars 人都随身佩带着一串能量项链。
在项链上有N 颗能量珠。
能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。
并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。
历年NOIP提高组试题难度列表
NOIP2008-D
NOIP2009-A
NOIP2009-B
火柴棒等式 模拟
传纸条 双栈排序
动态 规划
构造
潜伏者 模拟
Hankson的 趣味题
数学
枚举,优化/开表 0.8
历届搜索
题一般都比较
多维状态DP 0.7 难,搜索算法
本身简单,于
枚举,贪心/二分 图
0.4
是题目会提高
选手对其他方
模拟
【构造】
动态 规划
构 造, 贪心
多维DP
BFS/贪心,并查 集
平均难度系 数:0.27
构造类题 目一般没有明 确的算法,需
NOIP2010-D
引水入城
搜索 BFS
要选手仔细分 析题目的实
质,并得出解法。
这个解法通常不是唯一的。有时一个好的贪心可以得相当
多的分。有时搜索剪枝可以很大的提高效率。同样以多得分为
需要掌握
模拟,字符串
质数及其性 0.8 质,基础的实
子序列DP,贪心 优化
0.2
数操作,加法 原理和乘法原
置换群,贪心 0.2 理。此类题需
字符串,抽样检 测,表达式
区间环DP
要选手对数学 0.3 规律的灵感。
【图论】 0.6 平均难度系
资源分配DP,构 造
0.6
数:0.50 历届考察
模拟
动态规划/组合 数学,高精度
金明的预算 动态
方案
规划
作业调度方 案
模拟
2^k进制数
动态 规划
统计数字 模拟
字符串的展 开
模拟
矩阵取数游 动态
戏
规划
树网的核 图论
noip2009提高组模拟
杂务源程序名CHORE.???(PAS,C,CPP)可执行文件名CHORE.EXE输入文件名CHORE.IN输出文件名CHORE.OUTJohn的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。
比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。
尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。
当然,有些杂务必须在另一些杂务完成的情况下才能进行。
比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有在未给奶牛清洗乳房之前不能挤奶。
我们把这些工作称为完成本项工作的准备工作。
至少有一项杂务不要求有准备工作,这个可以最早着手完成的工作,标记为杂务1。
John有需要完成的n个杂务的清单,并且这份清单是有一定顺序的,杂务k(k>1)的准备工作只可能在杂务1..k-1中。
写一个程序从1到n读入每个杂务的工作说明。
计算出所有杂务都被完成的最短时间。
当然互相没有关系的杂务可以同时工作,并且,你可以假定John的农场有足够多的工人来同时完成任意多项任务。
输入第1行:一个整数n,必须完成的杂务的数目(3<=n<=10,000);第2 ~ n+1行:共有n行,每行有一些用1个空格隔开的整数,分别表示:* 工作序号(1..n,在输入文件中是有序的);* 完成工作所需要的时间len(1<=len<=100);* 一些必须完成的准备工作,总数不超过100个,由一个数字0结束。
有些杂务没有需要准备的工作只描述一个单独的0,整个输入文件中不会出现多余的空格。
输出一个整数,表示完成所有杂务所需的最短时间。
样例CHORE.IN71 5 02 2 1 03 3 2 04 6 1 05 1 2 4 06 8 2 4 07 4 3 5 6 0CHORE.OUT23开灯(light.pas/c/cpp)【题目描述】在一条无限长的路上,有一排无限长的路灯,编号为1,2,3,4,……。
noi2006第二十三届全国信息学奥林匹克竞赛B
第二十三届全国信息学奥林匹克竞赛NOI 2006第二试竞赛时间:2006年7月26日上午8:00-13:00题目名称最大获利聪明的导游神奇口袋guide bag 目录 profit可执行文件名 profit N/A bagbag.in输入文件名 profit.in guide1.in~guide10.inbag.out输出文件名 profit.out guide1.out~guide10.out秒每个测试点时限 2 秒 N/A 1测试点数目 10 10 10每个测试点分值 10 10 10是否有部分分无有无题目类型传统提交答案传统提交源程序须加后缀对于Pascal 语言 profit.pas N/A bag.pas对于C 语言 profit.c N/A bag.c对于C++ 语言 profit.cpp N/A bag.cpp 注意:最终测试时,所有编译命令均不打开任何优化开关除了提交答案题以外,其余两题只需要向输出文件输出一行,行内不得有多余空白字符,行末须有一个换行/回车符,格式不对不能得分。
第23 届全国信息学奥林匹克竞赛第二试 profit最大获利【问题描述】新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。
THU 集团旗下的CS&T 通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最优化等项目。
在前期市场调查和站址勘测之后,公司得到了一共N 个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第i 个通讯中转站需要的成本为P i(1≤i≤N)。
另外公司调查得出了所有期望中的用户群,一共M 个。
关于第i 个用户群的信息概括为A i, B i 和C i:这些用户会使用中转站A i 和中转站B i 进行通讯,公司可以获益C i。
2006年第十二届全国青少年信息学奥林匹克竞赛联赛
2006年第十二届全国青少年信息学奥林匹克竞赛联赛(NOIP ’2006)广东赛区成绩公告2006年第十二届全国青少年信息学奥林匹克竞赛联赛(NOIP’2006)广东赛区报名人数为5460人(提高组2943人,普及组2517人),参赛人数列全国第三,广东赛区连续第十二年获得优秀组织奖。
2006年广东赛区共有373所学校参赛,参赛人数与参赛学校数比去年略减。
本届提高组一等奖由全国统一测评,并按分配名额划线,结果提高组86位同学(含往年获奖37人)获联赛一等奖(即提高组省赛区一等奖),获保送上大学资格,占全国获省赛区一等奖790人(含往年获奖224人)中的10.89%(广东往年获奖的占全国往年获奖的16.52%),今届广东仍然是全国获保送上大学资格人数最多的省份,也是广东获保送资格人数最多的一年,表明广东省信息学竞赛不仅普及面而且尖子层人数也在全国前列。
23年的实践表明,GDOI(广东省青少年信息学(计算机)奥林匹克竞赛活动)是培养我们国家、我省计算机优秀后备人才的成功之路。
今年提高组二等奖及普及组一等奖由全国划定最低分数线及获奖范围,提高组三等奖及普及组二、三等奖由省竞赛委员会划定各奖项分数线,最后确认:提高组一、二、三等奖分数线分别为100、70、50,普及组一、二、三等奖分数线分别为300、200、110,除提高组一等奖分数线与全国持平外,其余各奖项均高于全国的最低分数线。
按照广东省信息学竞赛评委会制定的量的评估方法,综合测评省内各校在开展计算机教学和科技活动中取得的成绩,从全省373所参赛学校中评出成绩优异的前50所学校,其中前30所学校分获广东赛区学校团体一、二、三等奖(各10所),第31—50所学校获广东赛区表扬奖。
中山一中、韶关一中、北江中学等3所学校连续十二年保持广东赛区十强学校称号,广州六中也连续十年保持广东赛区十强学校称号,并与中山纪念中学、汕头金山中学、珠海一中、肈庆中学等8所学校再次获广东赛区十强学校称号的殊荣,中山纪念中学三鑫双语学校首次获广东赛区十强学校称号的殊荣,华南师大附中再次回到广东十强学校中。
NOIP2006提高组初赛试题_C++含答案
3
四.阅读程序写结果(共 4 题,每题 8 分,共计 32 分) 1. #include <iostream.h>
void main() {int i,u[4],v[4],x,y=10;
for(i=0;i<=3;i++) cin >>u[i];
v[0]=(u[0]+u[1]+u[2]+u[3])/7; v[1]=u[0]/((u[1]-u[2])/u[3]); v[2]=u[0]*u[1]/u[2]*u[3]; v[3]=v[0]*v[1]; x=(v[0]+v[1]+2)-u[(v[3]+3)%4]; if(x>10)
严谨求实的作风,既要努力奋进,又要胜不骄败不馁
三.问题求解(共 2 题,每题 5 分,共计 10 分)
1.将 2006 个人分成若干不相交的子集,每个子集至少有 3 个人,并且: (1)在每个子集中,没有人认识该子集的所有人。 (2)同一子集的任何 3 个人中,至少有 2 个人互不认识。 (3)对同一子集中任何 2 个不相识的人,在该子集中恰好只有 1 个人认识这两个人。 则满足上述条件的子集最多能有___________个?
历年NOIP(普及组提高组)试题难度列表
历年NOIP(普及组)难度分析 by Climber.pINOIP提高组复赛考察点详细分析动态规划:12 模拟:10数学:5 图论:4搜索:4 构造:3贪心:2【动态规划】平均难度系数:0.55此项为历届NOIP考察次数最多的知识点。
主要有 1.区间模型 2.子序列模型 3.资源分配模型以及一些简单的多维状态设计技巧。
动态规划可以与图,树,高精度等知识点配合出题。
【模拟】平均难度系数:0.76平均每届NOIP都会出现1个模拟题。
这种题一般算法很简单,需要选手细心理解题目意思,注意细节。
考察选手的代码实现能力。
【数学】平均难度系数:0.46需要掌握质数及其性质,基础的实属操作,加法原理和乘法原理。
此类题需要选手对数学规律的灵感。
【图论】平均难度系数:0.50历届考察点基本上都是 1.最短路问题和 2.特殊图的性质。
特殊图包括树,拓扑图,二分图等。
历届NOIP在图论上的考察并不是很多。
【搜索】平均难度系数:0.38历届搜索题一般都比较难,搜索算法本身简单,于是题目会提高选手对其他方面的要求。
主要有搜索优化和模拟。
写搜索题时应该以尽量多得分为目标。
【构造】平均难度系数:0.27构造类题目一般没有明确的算法,需要选手仔细分析题目的实质,并得出解法。
这个解法通常不是唯一的。
有时一个好的贪心可以得相当多的分。
有时搜索剪枝可以很大的提高效率。
同样以多得分为目标。
【【贪心】平均难度系数:0.75此类题需要选手对算法的直觉,贪心正确性一旦被证明,通常题目就简单了。
历届noip提高组复赛试题
N O I’95“同创杯”全国青少年信息学(计算机)奥林匹克竞赛分区联赛复赛试题(高中组)(上机编程,完成时间:210分钟)<1>编码问题:设有一个数组A:ARRAY[0..N-1] OF INTEGER;数组中存放的元素为0~N-1之间的整数,且A[i]≠A[j](当i≠j时)。
N-1),N1数据输入的方式为:NP1(颜色,为一个字母) N1(灯的数量)P2 N2……Q(结束标记,Q本身不是灯的颜色)程序要求:求出一种顺序的排列方案及排列总数。
<3> 设有一个四层的积木块,1~4层积木块的数量依次为:5,6,7,82个。
例如n=2时的比赛安排:队 1 2 3 4比赛 1==2 3==4 一天1==3 2==4 二天1==4 2==3 三天2.数制转换(20分)设有一个字符串A$的结构为:A$=’m<n>p’其中m为数字串(长度<=20),而n,p均为1或2位的数字串(其中所表达的内容在2-10之间)。
程序要求:从键盘上读入A$后(不用正确性检查),将A$中的数字串m(n进制),以p进制的形式输出。
例如:A$=’48<10>8’其意义为:将10进制数48,转换成8进制数输出。
输出结果为:48<10>=60<8>4.挖地雷(30分)在一个地图上有N 个地窖(N<=20),每个地窖中埋有一定数量的地雷。
同时,给出地窖之间的连接路径。
[题目要求] 当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接,当设计一(表示1g 砝码有a1个,2g 砝码有a2个,…,20g 砝码有a6个)输出方式:Total=N(N 表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)如输入:1_1_0_0_0_0 (注:下划线表示空格)输出:TOTAL=3 表示可以称出1g ,2g ,3g 三种不同的重量。
NOIp 2006 提高组 4 2^k进制数-凑数(生成)
NOIp 2006 提高组4 2^k进制数这题我以前写过的,现在就当是再温习一遍吧,思路就是递推(也就是动态规划)根据一个公式推导出来的DP方程,首先我用f[i][j]表示第i位数以j开头的数字共有多少个,那么最容易得到的一个转移方程是:f[i][j] = f[i - 1][j + 1] + f[i - 1][j + 2] + ....... + f[i - 1][n - 1] + f[i - 1][n].但是这个方程给我们的感觉就是一个字——太慢了,为什么这么慢呢?因为它就是这么慢,要把所有的一个个相加一次,但是注意到上面我画红的部分!就是用这个公式,这部分能够表示成啥?很简单啊:f[i][j + 1] = f[i - 1][j + 2] + ....... + f[i - 1][n - 1] + f[i - 1][n].那么智商高一点的人就看到玄机了,能够把f[i][j]简化成如下的形式:f[i][j] = f[i][j + 1] + f[i - 1][j + 1]如此一来程序就清晰多了,代码也很好写,要注意的是搜索时j是从后向前搜索,我还是使用面向对象的思想,先封装了一套int类型的,然后再修改成高精度类型的,int类型的(40分)如下:#include <stdio.h>typedef int num;num f[61][513];num ans;void give(num *a, int b){*a = b;}void add(num *a, num *b){*a += *b;}void output(num *a){printf("%d", *a);}int main(void){int i, j;int n, s, k, t, l;scanf("%d%d", &s, &n);k = 1 << s;for(i = 0; i < k; i++){give(&f[0][i], 1);}t = n / s;for(i = 1; i <= t; i++){for(j = k - i - 1; j >= 1; j--){add(&f[i][j], &f[i][j + 1]);add(&f[i][j], &f[i - 1][j + 1]);}}for(i = 1; i < t; i++){for(j = k - i - 1; j >= 1; j--){add(&ans, &f[i][j]);}}l = n - t * s;if(l == 0){l = k;}else{l = 1 << l;}for(i = 1; i < l; i++){add(&ans, &f[t][i]);}output(&ans);printf("\n");return 0;}详细修改了一番之后,发现主函数中错了,后来详细修改了一番,弄得我以为高精度写错了,仔细检查之后发现两个地方错了,第一个是数组开小了,本来是num f[61][513],后来发现要使用f[513][513],再一个就是不能够直接使用用(n - 1)/s,因为如果用30000/1(k = 1, w = 30000)的话那数组又会显得小了,需要f[30000][513],但是实际上又跟本用不到(因为k很小时最多只有!((1 << k) - 1)种情况,那样的情况很少)。
NOIP2006初赛试题及答案(提高组)
NOIP2006初赛试题(提高组Pascal语言)[日期:2006-10-25] 来源:作者:[字体:大中小]第十二届全国青少年信息学奥林匹克联赛初赛试题(提高组Pascal 语言二小时完成)●●全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效●●一、单项选择题(共10 题,每题1.5 分,共计15 分。
每题有且仅有一个正确答案.)。
1. 在以下各项中。
()不是CPU 的组成部分。
A. 控制器B. 运算器C. 寄存器D. ALUE. RAM2. BIOS(基本输入输出系统)是一组固化在计算机内()上一个ROM 芯片上的程序。
A. 控制器B. CPUC. 主板D. 内存条E. 硬盘3.在下面各世界顶级的奖项中,为计算机科学与技术领域作出杰出贡献的科学家设立的奖项是()。
A. 沃尔夫奖B. 诺贝尔奖C. 菲尔兹奖D. 图灵奖E. 南丁格尔奖4.在编程时(使用任一种高级语言,不一定是Pascal),如果需要从磁盘文件中输入一个很大的二维数组(例如1000*1000 的double 型数组),按行读(即外层循环是关于行的)与按列读(即外层循环是关于列的)相比,在输入效率上()。
A. 没有区别B. 有一些区别,但机器处理速度很快,可忽略不计C. 按行读的方式要高一些D. 按列读的方式要高一些E.取决于数组的存储方式。
5.在Pascal 语言中,表达式(21 xor 2)的值是()A. 441B. 42C.23D.24E.256.在Pascal 语言中,判断a不等于0且b不等于0的正确的条件表达式是()A. not a=0 or not b=0B. not((a=0)and(b=0))C. not(a=0 and b=0)D. (a<>0)or(b<>0)E. (a<>0)and (b<>0)7.某个车站呈狭长形,宽度只能容下一台车,并且只有一个出入口。
已知某时刻该车站状态为空,从这一时刻开始的出入记录为:“进,出,进,进,进,出,出,进,进,进,出,出”。
NOIP2006年题解解读
金明的预算方案
输入输出要求
【输入文件】 输入文件budget.in 的第1行,为两个正整数,用一个空格隔开: N m (其中N(<32000)表示总钱数,m(<60)为希望购买物品 的个数。) 从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据, 每行有3个非负整数 v p q (其中v表示该物品的价格(v<10000),p表示该物品的重要 度(1~5),q表示该物品是主件还是附件。如果q=0,表示该 物品为主件,如果q>0,表示该物品为附件,q是所属主件的 编号) 【输出文件】 输出文件budget.out只有一个正整数,为不超过总钱数的物品 的价格与重要度乘积的总和的最大值(<200000)。
2 3 4 5 6
i>=2,即对前i件物品,花费不超过k(0<=k<=10),价
7
8
9
10
1
2 3 4 5
0
0
0
0
0
0
0
0
0
0
0
0
16
16
16
If k>=w[i] then {第i件物品可要可不要, 不要 a[i,k]:=a[i-1,k]; 要 a[i,k]:=a[i-1,k-w[i]]+w[i]*v[i]} a[i,k]:=max(a[i-1,k], a[i-1,k-w[i]]+w[i]*v[i])
0 1 2 3 4 5 0 0 1 0 0 2 0 0 3 0 0 4 0 ? 5 0 6 0 7 0 8 16 9 16 10 16
W 8 4 3 4 2 V 2 5 5en {第i件物品可要可不要, 不要 a[2-1,4]=a[1,4]=0; 要 a[2-1,4-w[2]]+w[2]*v[2]=a[1,0]+4*5=20} max(a[2-1,k], a[2-1,k-w[2]]+w[2]*v[2])=max(0,20)
noip2006提高组解题报告及源程序
NOIP2006 Solutions2006届中国信息学奥林匹克联赛提高组解题报告by FaLLeNs问题一能量项链/Energy核心算法动态规划(原型石子合并问题)时间复杂度O(n3)空间复杂度O(n2)编码复杂度<50行实测时间<0.1s分析记head[i]为第i颗能量珠的首标记,也同时是它前面那颗能量珠的尾标记。
记录Energy[i,j]为从以Head[i]为首标记的能量珠开始顺时针数到以Head[j]为尾标记的能量珠为止所有能量珠组成的串合并后放出的最大能量。
那么对于Energy[i,j],若先合并从以Head[i]为首标记的能量珠开始顺时针数到以Head[k]为尾标记的能量珠为止的串,在合并以Head[k]为首标记的能量珠开始顺时针数到以Head[j]为尾标记的能量珠为止的串,然后将这两颗合并后的能量珠合并,放出的能量为Energy[i,k]+Energy[k,j]+Head[i]*Head[k]*Head[j]。
也就是说,状态转移方程为Energy[i,j]=Max{Energy[i,k]+Energy[k,j]+Head[i]*Head[k]*Head[j]} (i<=k<=j (i<j), k<i or k>j (i>=j))。
计算Energy[i,j]时,只会用到含有能量珠数目比它少的串在数组中的值,所以可以以串的能量珠数目为顺序规划,即按照k|(k+i) mod n=j的顺序进行规划。
评论如果枚举将能量项链变为串的开链位置,需要约n/2倍计算量,得到一个O(n4)的时间复杂度。
这是不需要的。
一个较优的贪心近似算法是每次找首标记最小的能量珠与它前面的能量珠合并。
对于NOIP中30%数据是正确的。
一个典型的反例是n=4,Head={10,3,2,3},贪心算法得到3*2*3+10*3*3+10*10*3=408,而最优解为10*3*2+10*2*3+10*10*3=420。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
NOIP2006提高组满分源代码(转自oifans)energy:CODE:{Problem: Noip 2006 Problem 1Algorithm: Dynamic Programming}constmaxn = 100;varn, i, j, k, p, ans:longint;data:array[1..maxn,1..2] of longint;dp:array[1..maxn,1..maxn] of longint;function max(a, b:longint):longint;beginif a > b then max:=a else max:=b;end;beginassign(input,'energy.in');reset(input);assign(output,'energy.out');rewrite(output);{ input }read(n);for i:=1 to n do read(data[i, 1]);{ Main }data[n, 2]:=data[1, 1];for i:=1 to n - 1 do data[i, 2]:=data[i+1, 1];fillchar(dp, sizeof(dp), 0);for p:=1 to n-1 dofor i:=1 to n dobeginj:=(i + p - 1) mod n + 1;if i < j thenbeginfor k:=i to j-1 dodp[i, j]:=max(dp[i, j], dp[i, k] + dp[k+1, j] +data[i, 1] * data[k, 2] * data[j, 2]);end;if i > j thenbeginfor k:=i to n-1 dodp[i, j]:=max(dp[i, j], dp[i, k] + dp[k+1, j] +data[i, 1] * data[k, 2] * data[j, 2]);dp[i, j]:=max(dp[i, j], dp[i, n] + dp[1, j] +data[i, 1] * data[n, 2] * data[j, 2]);for k:=1 to j-1 dodp[i, j]:=max(dp[i, j], dp[i, k] + dp[k+1, j] +data[i, 1] * data[k, 2] * data[j, 2]);end;end;{ output }ans:=-1;for i:=1 to n dobeginj:=(i + n - 2) mod n + 1;ans:=max(ans, dp[i, j]);end;writeln(ans);close(input);close(output);end.JSP:CODE:{Problem: Noip 2006 Problem 3Algorithm: Simulation}constmaxn = 20;maxm = 20;maxs = 5000;typeTseq = recordst, ed:longint;end;varn, m, i, j, k, ans:longint;ma, tim, x, y:longint;t:array[1..maxn] of longint;data, a:array[1..maxn*maxm] of longint;num:array[1..maxn,1..maxm] of longint;time:array[1..maxn,1..maxm] of longint;free:array[1..maxm,1..maxs] of Tseq;count:array[1..maxm] of longint;last:array[1..maxn] of longint;function max(a, b:longint):longint;beginif a > b then max:=a else max:=b;end;function find_free(k, ma, tim:longint; var x, y:longint):longint;vari, minx, best:longint;beginminx:=maxlongint;for i:=1 to count[ma] doif free[ma, i].ed - free[ma, i].st >= tim thenif last[k] <= free[ma, i].st thenbeginif free[ma, i].st < minx thenbeginminx:=free[ma, i].st;best:=i;end;end elseif (last[k] > free[ma, i].st) and (last[k] + tim <= free[ma, i].ed) then beginif last[k] < minx thenbeginminx:=last[k];best:=i;end;end;find_free:=best;x:=minx;y:=x + tim;end;beginassign(input,'jsp.in');reset(input);assign(output,'jsp.out');rewrite(output);{ input }read(m, n);for i:=1 to m * n do read(data[i]);for i:=1 to n dofor j:=1 to m do read(num[i, j]); for i:=1 to n dofor j:=1 to m do read(time[i, j]);{ Main }fillchar(t, sizeof(t), 0);for i:=1 to n * m dobegininc(t[data[i]]);a[i]:=t[data[i]];end;fillchar(last, sizeof(last), 0);for i:=1 to m dobegincount[i]:=1;free[i, 1].st:=0;free[i, 1].ed:=maxlongint;end;for i:=1 to n * m dobeginma:=num[data[i], a[i]];tim:=time[data[i], a[i]];k:=find_free(data[i], ma, tim, x, y);inc(count[ma]);free[ma, count[ma]].st:=y;free[ma, count[ma]].ed:=free[ma, k].ed;free[ma, k].ed:=x;last[data[i]]:=y;end;{ output }ans:=-1;for i:=1 to m dofor j:=1 to count[i] doif free[i, j].ed = maxlongint thenans:=max(ans, free[i, j].st);writeln(ans);close(input);close(output);end.budget:CODE:{Problem: Noip 2006 Problem 2Algorithm: Dynamic Programming}constmaxm = 61;maxn = 32000;varn, m, i, j, k, ans:longint;cost, p, q, cost_tmp, p_tmp:array[1..maxm] of longint; data:array[1..maxm] of longint;flag:array[1..maxm] of byte;dp:array[1..maxm+1,-1..2,0..maxn] of longint;function max(a, b:longint):longint;beginif a > b then max:=a else max:=b;end;beginassign(input,'budget.in'); reset(input);assign(output,'budget.out'); rewrite(output);{ input }read(n, m);for i:=1 to m doread(cost[i], p[i], q[i]);{ Main }k:=0;for i:=1 to m doif q[i] = 0 thenbegininc(k);data[k]:=i;flag[k]:=1;for j:=1 to m doif q[j] = i thenbegininc(k);data[k]:=j;flag[k]:=0;end;end;// huan yuan costfor i:=1 to m dobegincost_tmp[i]:=cost[data[i]]; p_tmp[i]:=p[data[i]]; end;cost:=cost_tmp;p:=p_tmp;for i:=1 to m+1 dofor j:=-1 to 2 dofor k:=0 to n dodp[i, j, k]:=-1;dp[1, -1, 0]:=0;for i:=1 to m dofor k:=0 to N dobeginif flag[i] = 1 thenbeginfor j:=-1 to 2 dobeginif dp[i, j, k] = -1 then continue;if k + cost[i] <= n thendp[i+1, 0, k+cost[i]]:=max(dp[i+1, 0, k+cost[i]], dp[i, j, k] + cost[i] * p[i]);dp[i+1, -1, k]:=max(dp[i+1, -1, k], dp[i, j, k]);end;end;if flag[i] = 0 thenbeginfor j:=-1 to 2 dobeginif dp[i, j, k] = -1 then continue;case j of-1 : dp[i+1, j, k]:=max(dp[i+1, j, k], dp[i, j, k]);0, 1 : beginif k + cost[i] <= n thendp[i+1, j+1, k+cost[i]]:=max(dp[i+1, j+1, k+cost[i]], dp[i, j, k] + cost[i] * p[i]);dp[i+1, j, k]:=max(dp[i+1, j, k], dp[i, j, k]);end;2 : dp[i+1, j, k]:=max(dp[i+1, j, k], dp[i, j, k]);end;end;end;end;{ output }ans:=0;for j:=-1 to 2 dofor k:=0 to n doans:=max(ans, dp[m+1, j, k]);writeln(ans);close(input);close(output);end.digitalCODE:const inf ='digital.in';ouf ='digital.out';maxn =512;pw :array[1..9]of longint=(2,4,8,16,32,64,128,256,512);mol =1000000;type bignum =array[0..50]of longint;var k,w,n,i,p,j :longint;f :array[boolean,0..maxn]of bignum;ans :bignum;procedure init;beginassign(input,inf);reset(input);readln(k,w);n:=1;for i:=1 to k don:=n*2;close(input);end;procedure hiadd(var a,b:bignum);var i,j,n,tmp :longint;ta :bignum;beginif a[0]<b[0] then a[0]:=b[0];for i:=1 to a[0] doa[i]:=a[i]+b[i];for i:=1 to a[0] dobegintmp:=a[i] div mol; inc(a[i+1],tmp);a[i]:=a[i] mod mol;end;if a[a[0]+1]>0 then inc(a[0]);end;procedure cal;var now,last :boolean;change :boolean;max :longint;beginp:=k;now:=true; last:=false;fillchar(f,sizeof(f),0);for i:=0 to n dobeginf[now,i][0]:=1; f[now,i][1]:=1; end;dec(n);if w>k*n then w:=k*n;ans[0]:=1; ans[1]:=0;repeatnow:=not now; last:=not last; fillchar(f[now],sizeof(f[now]),0); change:=false;inc(p,k);if p>w thenbegindec(p,k); max:=w-p; p:=w;endelse max:=k;hiadd(f[now,n-1],f[last,n]);for i:=n-2 downto 0 dobeginf[now,i]:=f[now,i+1];hiadd(f[now,i],f[last,i+1]);end;if p>2*k then hiadd(ans,f[now,0]); until p=w;for i:=1 to pw[max]-1 dohiadd(ans,f[now,i]);assign(output,ouf);rewrite(output);n:=ans[0];write(ans[n]);for i:=n-1 downto 1 dobeginmax:=mol div 10;while max<>0 dobeginwrite(ans[i] div max mod 10);max:=max div 10;end;end;writeln;close(output);end;begininit; cal;end.。