NOIP 2006年普及组解题报告

合集下载

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背包问题,只是多了附件这个条件。

【通用】信息学奥赛NOIP普及组历届试题分析.ppt

【通用】信息学奥赛NOIP普及组历届试题分析.ppt
枚举法其实是最简单的搜索算法。
.,.,
4
珠心算测验 (noip2014普及组第一题)
珠心算是一种通过在脑中模拟算盘变化来完成快 速运算的一种计算技术。珠心算训练,既能够开 发智力,又能够为日常生活带来很多便利,因而 在很多学校得到普及。
某学校的珠心算老师采用一种快速考察珠心算加 法能力的测验方法。他随机生成一个正整数集合, 集合中的数各不相同,然后要求学生回答:其中 有多少个数,恰好等于集合中另外两个(不同的) 数之和? 最近老师出了一些测验题,请你帮忙求 出答案。
不过,如果把调查结果就以这种方式呈现出来,大 多数人肯定不会满意。因为这个比例的数值太大, 难以一眼看出它们的关系。对于上面这个例子,如 果把比例记为 5:3,虽然与 真实结果有一定的误差, 但依然能够较为准确地反映调查结果,同时也显得 比较直观。
现给出支持人数 A,反对人数 B,以及一个上限 L, 请你将 A 比 B 化简为 A’比 B’,要求在 A’和 B’均 不大于 L 且 A’和 B’互质(两个整数的最大公约数 是 1)的前提下,A’/B’ ≥ A/B 且 A’/B’ - A/B 的值 尽可能小。
输入样例 2 23 ?*? *??
输出样例 2 mine.out 2*1 *21
对于 100%的数据,1≤n≤100,1≤m≤100
.,.,
10
比例简化 (noip2014普及组第二题)
在社交媒体上,经常会看到针对某一个观点同意与 否的民意调查以及结果。例如,对某 一观点表示 支持的有 1498 人,反对的有 902 人,那么赞同与 反对的比例可以简单的记为1498:902。
.,.,
11
比例简化 (noip2014普及组第二题)
输入格式 输入共一行,包含三个整数 A,B,L,每两个整

NOIP2006普及组C 题目及答案

NOIP2006普及组C  题目及答案

第十二届全国青少年信息学奥林匹克联赛初赛试题 2006(普及组C++ 语言二小时完成)●●全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效●●一、单项选择题(共20题,每题1.5分,共计30分。

每题有且仅有一个正确答案.)1. 在下面各世界顶级的奖项中,为计算机科学与技术领域做出杰出贡献的科学家设立的奖项是()。

A. 沃尔夫奖B. 诺贝尔奖C. 菲尔兹奖D. 图灵奖2. 在下列各软件中,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。

A. gcc/g++B. Turbo PascalC. RHIDED. free pascal3. 以下断电之后仍能保存数据的有()。

A. 寄存器B. ROMC. RAMD. 高速缓存4.Linux是一种( )。

A. 绘图软件B. 程序设计语言C. 操作系统D. 网络浏览器5. CPU是( )的简称。

A. 硬盘B. 中央处理器C. 高级程序语言D. 核心寄存器6. 在计算机中,防火墙的作用是()。

A. 防止火灾蔓延B.防止网络攻击C. 防止计算机死机D. 防止使用者误删除数据7. 在下列关于计算机语言的说法中,不正确的是()。

A. Pascal和C都是编译执行的高级语言B. 高级语言程序比汇编语言程序更容易从一种计算机移植到另一种计算机上C. C++是历史上的第一个支持面向对象的计算机语言D. 与汇编语言相比,高级语言程序更容易阅读8. 在下列关于计算机算法的说法中,不正确的是()。

A. 一个正确的算法至少要有一个输入B. 算法的改进,在很大程度上推动了计算机科学与技术的进步C. 判断一个算法的好坏的主要标准是算法的时间复杂性与空间复杂性D. 目前仍然存在许多涉及到国计民生的重大课题,还没有找到能够在计算机上实施的有效算法9. 在下列各种排序算法中,不是以“比较”作为主要操作的算法是()。

A. 选择排序B. 冒泡排序C. 插入排序D. 基数排序10.在编程时(使用任一种高级语言,不一定是C++),如果需要从磁盘文件中输入一个很大的二维数组(例如1000*1000的double型数组),按行读(即外层循环是关于行的)与按列读(即外层循环是关于列的)相比,在输入效率上()。

NOIP2006年题解解读

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解题报告-陈启峰
显然,在这些约定下,对于给定的安排顺序,符合该安排顺序的实施方案是 唯一的,请你计算出该方案完成全部任务所需的总时间。 【输入文件】
输入文件 jsp.in 的第 1 行为两个正整数,用一个空格隔开:
500比较小,用搜索是可以过全部数据的。比赛时我写的是一个 windows
下可以所有数据的搜索程序,可是在 linux 下就无法编译~-~。 这里就讲讲与背包算法相似的动态规划。首先,我们把主件和其附件看成是
一个整体。 当主件有 0 个附件时,有 2 种选择:选主件、什么都不选; 当主件有 1 个附件时,有 3 种选择:主件和附件、附件、什么都不选; 当主件有 2 个附件时,有 5 种选择:主件和两个附件,附件 1、附件 2、附
关于竞赛中不同语言使用限制的说明
一.关于使用 Pascal 语言与编译结果的说明
1.对于 Pascal 语言的程序,当使用 IDE 和 fpc 编译结果不一致时,以 fpc 的 编译结果为准。
2.允许使用数学库(uses math 子句),以及 ansistring。但不允许使用编译开 关(最后测试时 pascal 的范围检查开关默认关闭:{$R-,Q-,S-}),也不支 持与优化相关的选项。
(2) 同一时刻每一台机器至多只能加工一个工件。
另一方面,在安排后面的操作时,不能改动前面已安排的操作的工作状态。 由于同一工件都是按工序的顺序安排的,因此,只按原顺序给出工件号,仍 可得到同样的安排顺序,于是,在输入数据中,我们将这个安排顺序简写为“1 1 2 3 3 2”。
第 7/15页

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数
vpq (其中 v 表示该物品的价格(v<10000),p 表示该物品的重要度(1~5), q 表示该物品是主件还是附件。如果 q=0,表示该物品为主件,如果 q>0,表示 该物品为附件,q 是所属主件的编号) 【输出文件】

NOIP2006普及组初赛试题答案

NOIP2006普及组初赛试题答案

第十二届全国青少年信息学奥林匹克联赛初赛试题(普及组Pascal语言二小时完成)●●全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效●●一、单项选择题(共20题,每题1.5分,共计30分。

每题有且仅有一个正确答案.)。

1.在下面各世界顶级的奖项中,为计算机科学与技术领域做出杰出贡献的科学家设立的奖项是()。

A.沃尔夫奖B.诺贝尔奖C.菲尔兹奖D.图灵奖2.在下列各软件中,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。

A.gcc/g++B.Turbo PascalC.RHIDED.free pascal3.以下断电之后仍能保存数据的有()。

A.寄存器B.ROMC.RAMD.高速缓存4.Linux是一种()。

A.绘图软件B.程序设计语言C.操作系统D.网络浏览器5.CPU是()的简称。

A.硬盘B.中央处理器C.高级程序语言D.核心寄存器6.在计算机中,防火墙的作用是()。

A.防止火灾蔓延B.防止网络攻击C.防止计算机死机D.防止使用者误删除数据7.在下列关于计算机语言的说法中,不正确的是()。

A.Pascal和C都是编译执行的高级语言B.高级语言程序比汇编语言程序更容易从一种计算机移植到另一种计算机上C.C++是历史上的第一个支持面向对象的计算机语言D.与汇编语言相比,高级语言程序更容易阅读8.在下列关于计算机算法的说法中,不正确的是()。

A.一个正确的算法至少要有一个输入B.算法的改进,在很大程度上推动了计算机科学与技术的进步C.判断一个算法的好坏的主要标准是算法的时间复杂性与空间复杂性D.目前仍然存在许多涉及到国计民生的重大课题,还没有找到能够在计算机上实施的有效算法9.在下列各种排序算法中,不是以“比较”作为主要操作的算法是()。

A.选择排序B.冒泡排序C.插入排序D.基数排序10.在编程时(使用任一种高级语言,不一定是Pascal),如果需要从磁盘文件中输入一个很大的二维数组(例如1000*1000的double型数组),按行读(即外层循环是关于行的)与按列读(即外层循环是关于列的)相比,在输入效率上()。

【NOIP2006普及组】开心的金明

【NOIP2006普及组】开心的金明

【NOIP2006普及组】开⼼的⾦明
看过题后,你可能会发现这是很典型的0-1背包问题,即要么选择这件要么不选。

0-1背包问题最经典的解法就是动态规划了。

当然这道题的数据范围较⼩,也可以⽤暴搜(暴⼒搜索)来做,即枚举所有情况。

我们⽤递归来实现⼀下。

对于每⼀件物品就模拟两种情况选或者不选,千万不要漏掉哪⼀种情况,最后求取最⼤值就好了。

(由于我们当时模拟赛,所以写了⽂件读取数据,请见谅。


好了,暴搜的解法就介绍到这⾥,接下来,要介绍经典解法——动态规划。

动态规划最重要的就是建⽴递推式,根据上⾯讲解我们已经明确了对于每个物品依次检查选或不选,⽤dp[i][j]表⽰前 i 个物品在 j ⾦额下的最优解(结果最⼤)。

如果j放不下第i个物品的话,那么就只能从编号为[1,i-1]的物品中选择了,也就是dp[i-1][j]的值。

所以,
dp[i][j] = dp[i-1][j]; (其中,j < v[i])
那么j可以放的下这个物品的时候应该怎么办呢?很明显,我们有两种选择,选或不选,之后我们取较⼤的值。

选 dp[i-1][j-v[i]]+v[i]*p[i];
不选 dp[i-1][j];
所以我们得到递推式
dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]]+v[i]*p[i]);(其中,j>=v[i])
把两种情况整理⼀下,
怎么样?思路明确多了吧!
根据递推式来写代码就好了。

最后附上AC代码。

NOIP2006普及其组C题目及其规范标准答案

NOIP2006普及其组C题目及其规范标准答案

第十二届全国青少年信息学奥林匹克联赛初赛试题 2006(普及组C++ 语言二小时完成)●●全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效●●一、单项选择题(共20题,每题1.5分,共计30分。

每题有且仅有一个正确答案.)1. 在下面各世界顶级的奖项中,为计算机科学与技术领域做出杰出贡献的科学家设立的奖项是()。

A. 沃尔夫奖B. 诺贝尔奖C. 菲尔兹奖D. 图灵奖2. 在下列各软件中,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。

A. gcc/g++B. Turbo PascalC. RHIDED. free pascal3. 以下断电之后仍能保存数据的有()。

A. 寄存器B. ROMC. RAMD. 高速缓存4.Linux是一种( )。

A. 绘图软件B. 程序设计语言C. 操作系统D. 网络浏览器5. CPU是( )的简称。

A. 硬盘B. 中央处理器C. 高级程序语言D. 核心寄存器6. 在计算机中,防火墙的作用是()。

A. 防止火灾蔓延B.防止网络攻击C. 防止计算机死机D. 防止使用者误删除数据7. 在下列关于计算机语言的说法中,不正确的是()。

A. Pascal和C都是编译执行的高级语言B. 高级语言程序比汇编语言程序更容易从一种计算机移植到另一种计算机上C. C++是历史上的第一个支持面向对象的计算机语言D. 与汇编语言相比,高级语言程序更容易阅读8. 在下列关于计算机算法的说法中,不正确的是()。

A. 一个正确的算法至少要有一个输入B. 算法的改进,在很大程度上推动了计算机科学与技术的进步C. 判断一个算法的好坏的主要标准是算法的时间复杂性与空间复杂性D. 目前仍然存在许多涉及到国计民生的重大课题,还没有找到能够在计算机上实施的有效算法9. 在下列各种排序算法中,不是以“比较”作为主要操作的算法是()。

A. 选择排序B. 冒泡排序C. 插入排序D. 基数排序10.在编程时(使用任一种高级语言,不一定是C++),如果需要从磁盘文件中输入一个很大的二维数组(例如1000*1000的double型数组),按行读(即外层循环是关于行的)与按列读(即外层循环是关于列的)相比,在输入效率上()。

noip2006

noip2006

NOIP2006复赛普及组解题报告【第一题解题思想】:这道题属于容易题,但是题目难度大于NOIP2005和2004普及组第一题,和去年第二题难度相当后者略低一些。

解法1:我们可以用先去掉重复(读入第i个数,和他前面的i-1个数比较),然后用简单排序和冒泡排序排序,最后输出结果。

解法2:运用插入排序(略加修改),边排序边除掉重复。

解法3:直接排序,不去掉重复,计算出不重复的元素个数,输出不重复的元素即可。

如果用数组A存储这些随机数,对于2到N个元素需要比较A是否等于A[i-1]。

解法4:开一个1到1000初值均为假的布尔数组A。

用整型变量X读入N个随机数,赋A[X]的值为真。

统计数组中值为真的元素个数即M,从i从1到1000输出A值为真的i。

这种方法可以算作哈希表的简单应用。

解法5:很多人想到排序,效率大概是O(n^2)吧,其实还有个更简单的方法。

用一个1到1000的数组储存每个数的出现情况,t每出现一次,a[t]=a[t]+1,而且,同时操作if(a[t]>1) 则总数=总数-1。

然后从1到1000的循环,如果a≠0,输出,这样就根本不用排序了。

大概这个应该是最优算法吧。

O(n)的效率。

program random(input,output);var a:array[1..1000] of integer; / ’a是记录数组,相当于数轴,与数一一对应,temp 是临时存储数据,n和题目一样,记录不相同的数的个数’ /i,m,temp,n:integer;beginassign(input,'d:\data\random.in');reset(input);assign(output,'d:\data\random.out');rewrite(output);read(n);readln;fillchar(a,sizeof(a),0); /*初始化数组为0,pascal有fillchar*/m:=n;for i:=1 to n dobeginread(temp);a[temp]:=a[temp]+1; /*记录是哪个数*/if a[temp]>1 then dec(m);end;write(m);writeln;for i:=1 to 1000 doif a>0 then / *如果a不为0。

NOIP普及组历届试题分析

NOIP普及组历届试题分析

8.
readln;
20.
9. end;
21.
10. for i:=1 to n do
22.
11. begin
23.
12. for j:=1 to m do
24.
13.
begin
25.
14.
s:=0;
26.
15.
if a[i,j]='*' then write(a[i,j2])7.
28.
29.
30.
else begin if a[i][j-1]='*' then inc(s); if a[i][j+1]='*' then inc(s); if a[i+1][j-1]='*' then inc(s); if a[i+1][j+1]='*' then inc(s); if a[i+1][j]='*' then inc(s); if a[i-1][j-1]='*' then inc(s); if a[i-1][j+1]='*' then inc(s); if a[i-1][j]='*' then inc(s); write(s);
8.
begin
9.
read(f[i]);
10.
vis[f[i]]:=1;
11.
end;
12. ans:=0;
13. for a:=1 to n do
14.
for b:=1 to n do
15.
if (vis[f[a]+f[b]]=1)and(a<>b) then

NOIP2006第十二届普及组初赛题目C++

NOIP2006第十二届普及组初赛题目C++

第十二届全国青少年信息学奥林匹克联赛初赛试题(2006 NOIP 普及组C++ 语言二小时完成)一、单项选择题(共20题,每题1.5分,共计30分。

每题有且仅有一个正确答案.)。

1. 在下面各世界顶级的奖项中,为计算机科学与技术领域做出杰出贡献的科学家设立的奖项是()。

A. 沃尔夫奖B. 诺贝尔奖C. 菲尔兹奖D. 图灵奖2. 在下列各软件中,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。

A. gcc/g++B. Turbo PascalC. RHIDED. free pascal3. 以下断电之后仍能保存数据的有()。

A. 寄存器B. ROMC. RAMD. 高速缓存4.Linux是一种( )。

A. 绘图软件B. 程序设计语言C. 操作系统D. 网络浏览器5. CPU是( )的简称。

A. 硬盘B. 中央处理器C. 高级程序语言D. 核心寄存器6. 在计算机中,防火墙的作用是()。

A. 防止火灾蔓延B.防止网络攻击C. 防止计算机死机D. 防止使用者误删除数据7. 在下列关于计算机语言的说法中,不正确的是()。

A. Pascal和C都是编译执行的高级语言B. 高级语言程序比汇编语言程序更容易从一种计算机移植到另一种计算机上C. C++是历史上的第一个支持面向对象的计算机语言D. 与汇编语言相比,高级语言程序更容易阅读8. 在下列关于计算机算法的说法中,不正确的是()。

A. 一个正确的算法至少要有一个输入B. 算法的改进,在很大程度上推动了计算机科学与技术的进步C. 判断一个算法的好坏的主要标准是算法的时间复杂性与空间复杂性D. 目前仍然存在许多涉及到国计民生的重大课题,还没有找到能够在计算机上实施的有效算法9. 在下列各种排序算法中,不是以“比较”作为主要操作的算法是()。

A. 选择排序B. 冒泡排序C. 插入排序D. 基数排序10.在编程时(使用任一种高级语言,不一定是C++),如果需要从磁盘文件中输入一个很大的二维数组(例如1000*1000 的double 型数组),按行读(即外层循环是关于行的)与按列读(即外层循环是关于列的)相比,在输入效率上()。

NOI2006解题报告

NOI2006解题报告

Day1:#1:网络收费(network)这道题完全不会,当时写了个搜索拿了40分把配对收费规则转化一下,对于任两个用户i,j,设它们的最近公共祖先(LCA)是p如果在p上na<nb,则i,j中谁是A谁支付F[i,j]的费用如果在p上na≥nb,则i,j中谁是B谁支付F[i,j]的费用这样的转化让点对交费转移到单点交费,为dp提供了前提,且最后的总费用不变整个模型是一棵完全二叉树,设计树形dpdp[i,j,k]:在点i所管辖的所有用户中,有j个用户为A在i的每个祖先u上,如果na<nb,则标0,否则标1,这个数列可以用二进制表示,用k记录在这种情况下的最少花费状态转移方程:其实就是将j个用户分配给i的左右子节点,并更改kdp[i,j,k]=min{dp[i.lt,u,k+%s],dp[i.rt,j-u,k+%s]}+%s表示在数列上加入节点i的标号,i.lt、i.rt分别表示i的左右子节点边界:当i是叶节点时,可以根据k算出i与其它用户配对收费时所要交的费用,再根据i的初始情况加上AB的转化费用复杂度分析:设m=2n粗略看来,空间复杂度是O(m3),时间复杂度是O(m4),对于本题的数据可以同时MLE和TLE了如果你看到这样复杂度就想别的方法了,那我只能同情你了,因为这只是很粗略的复杂度分析把根节点看做第0层,叶节点就是第n层,对于任意的第i层,A用户的个数最多只有2n-i,而祖先结点只有i个,即k最大只有2i把dp[i,j,k]的后两维合并成一维,空间复杂度其实只有O(m2)再看时间复杂度,对于第i层,有2i个节点,每个节点的状态数是O(m)的,状态转移的复杂度是O(2n-i),所以每层的复杂度是O(m2)总共有n层,所以状态转移的时间复杂度是O(m2n)考虑边界,如果是朴素的计算费用,即枚举所有用户(O(m)),再算出LCA(O(n)),复杂度是O(mn)边界数高达O(m2),这样计算边界的复杂度就是O(m3n)!加一些预处理,提前算出所有点的LCA,复杂度是O(m2n)设dpx[i,j]表示第i个用户,在向上数第j个祖先节点处配对收费时所要交的费用,dpx可以在O(m2n)的时间内计算出来计算每个边界时可以根据k在O(n)时间内计算出配对费用,这样计算边界的复杂度降到O(m2n)至此空间复杂度和时间复杂度都降到了可以承受的地步,在具体实现时,要用记忆化搜索和二进制的位运算ps.说了一大堆,感觉不如直接看我的程序#2:生日快乐(happybirthday)这次NOI唯一一道做得比较满意的题目,算法和标准算法完全一样,得分90数据结构就是二叉树,为了使之平衡,这里用treap(当然也可以用splay,不过好像treap比splay快一些)为了记录每个元素排序后的位置,每个节点加num记录该节点为根的子树上的节点总数每次收到一个礼物,将它插入到treap中,根据num可以得到它的位置pl然后根据男生或女生得到要吃掉的礼物的位置(pl±L),根据num确定该节点s如果s不存在或者没有果冻,那么tell(-1)否则将s从treap中删除(先把s移到叶节点,然后删除),改变s的果冻数,然后重新插入到treap中注意在操作中更改num的值时间复杂度是O(nlogn)ps.重新编了一下,最后一个数据仍然TLE,大概我的treap写垃圾了- -b#3:千年虫(worm)用一个小时看出来是用dp,用一个小时优化方程,交上去以后才发现:方程写错了后来听人说这道题和HNOI的某道题一样,抓狂,后悔没做省选题……如果你语文够强,在分析完题目的描述以后应该可以得到这样的结论:以一边为例,则千年虫的外形是一个类似梳子的样子(事实上,HNOI那道题好像就是叫梳子),就是一段高,一段低而我们要做的,就是添加尽量少的方块,使得外形满足上诉的样子,这样很容易想到dp设dp[i,j,s]表示前i行,第i行的状态是s(s=0,第i行处于凹的一段;s=1,第i行处于凸的一段),且第i 行的最终高度是j的状态下最小添加的方块数dp[i,j,s]=min{dp[i-1,j,s],dp[i-1,k,1-s](s=1,k<j s=0,k>j)}+(j-h[i]),其中h[i]是第i行的原始高度时间复杂度是O(n3)的,根据状态转移方程可以把复杂度降到O(n2)但是对于本题的极限数据,这样的复杂度仍然不能令人满意bamboo的BT方法:其实就是减少需要计算的状态量,我将其理解为建立在贪心基础上的dp对于第i行,设它的初始高度为a[i],最终高度为b[i]能够证明的是:b[i]的取值范围只能是[a[j],a[j]+2](|j-i|≤2)证明过程非常繁琐,大体思想就是分情况讨论,对于每种情况,或者找到确定的j,或者说明不是最优解(证明过程请参加讲题大会时的ppt,因为情况太多,我只是大概的证明了处在凹的一段)这样对于第i行只需要计算常数个最终长度,而对于每个状态的决策也只有常数个,所以复杂度是O(n)下载:worm.pptDay2:#1:最大获利(profit)NOI历史上第一道网络流的题目(为什么偏偏让我赶上了- -b)这道题和《算法艺术》317页那道题几乎一样,郁闷的发现自己看过,更郁闷的是NOI的时候忘了建立模型,将每个用户和中转站看作点,另外添加源点s,汇点t添加下列边:①s到中转站i,容量为P i②用户i到中转站A i和B i,容量为∞③用户i到t的边,容量为C i考虑这个模型的割割边不可能是②中的边,这保证了解的合法性属于①的割边表示付出的代价属于③的割边表示损失的利益显然割的量越小越好,这样这道题就转换成一个最小割的问题根据最大流最小割定理,设sum=∑C i,我们只要求出该网络的最大流maxflow,则sum-maxflow就是最大获利至此我们已经分析出了这道题的模型,但是,让我们看一下9、10两个BT数据吧,你会发现,即使用目前最快的HLPP也会严重TLE可能你也听说过要用贪心来做一个初始流,然后在这个基础上求最大流但其实不是随便贪都可以的,事实上,对于最后两个点的出解时间,在很大程度上取决于贪心的初始解与最优解的逼近程度这样的话就需要一个比较好的贪心,这里介绍一下ZhY大牛的贪心砍掉s和t,将模型缩减为一个二分图,并设cp[i]=第i个点到s或t的那条边的容量,degree[i]=∑cp[j](j 与i相邻)每次找到一个degree最小的点i,按照degree递增的顺序处理每个与它相邻的点j,在连接i,j的边上进行增广具体实现时需要用heap大概思想就是这样,至于为什么这样我也不太清楚(看的ZhY的C++的程序,按照这个思想编的,可是贪心的结果与ZhY的还是有一些差距)接下来,在求得初始流以后该如何求最大流呢?HLPP仍然严重TLE (汗)BFS求最短增广路,最大数据用时6.xx sDFS多路增广(具体实现请参见我的程序),仅仅是能卡着点过(关闭其它耗内存的东西 2.xx s,开一个wmplayer就TLE)#2:聪明的导游(guide)这道题向GHY大牛请教了一种超级BT的方法首先看最后两个数据,不难发现是一棵树对于一棵树,最优解就是这棵树上的最长路径对这个问题存在最优方法:从任一点e出发,找到e的最远点s,在从s出发,找到s的最远点t,则s到t的路径上所有点就是所求证明略过(可以参见《信息学奥林匹克竞赛-国际国内分类试题精解(上册)》78页)现在的问题是,对于一个任意图(数据1-8),如何求得最优解如果可以去掉一些边,使任意图变成一棵树,则可以用上诉方法来求最优解一个大致的算法产生了:在原图的基础上随机生成一棵树,然后求这棵树上的最优解,取其中最优的输出考虑以下两种树:显然第一种树的最优解优于第二种树在用DFS生成树的过程中加入一些贪心因素,优先扩展度小的节点在此基础上加入一些随机因素:随机确定根节点对于度数相同的节点,随机交换顺序注意这里节点的度数应不包括后向边,这就要求在DFS的过程中动态更新节点的度数ps.用这种方法应该可以得满分,但我的程序只拿到99分(第2个点9分)#3:神奇口袋(bag)这是第二试最简单的一道题,也是这次NOI最简单的一道考察的只是很简单的数学知识+高精度乘法,可惜看错题了,哭简单一些的描述就是每次随机选择一种颜色的球,将数量+d整个大框架就是乘法原理,对于每次取球,如果没有在x i中,那么这次操作称为“自由取球”,否则将颜色y i的球的数量a/此时球的总数作为乘数乘到结果中,并将颜色y i的球的数量+d,称作“定向取球”可以证明,自由取球对任意球被取到的几率P i没有影响证明很简单,就不说了这样就可以忽略掉所有的自由取球操作,即每一步都是定向取球剩下的就只是高精度乘法了对于最后分数化简的问题,因为分子分母最多只有20000,所以只要建立一个20000以内的素数表连高精度除法都不需要,只要先将分子分母都化简掉再高精度乘起来输出就行了。

noip2006提高组解题报告及源程序

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。

[洛谷P1062NOIP2006普及组]数列

[洛谷P1062NOIP2006普及组]数列

[洛⾕P1062NOIP2006普及组]数列⾸先题⾯是这样的:给定⼀个正整数 k(3≤k≤15) ,把所有k的⽅幂及所有有限个互不相等的k的⽅幂之和构成⼀个递增的序列,例如,当 k=3 时,这个序列是:1,3,4,9,10,12,13,…因为所有的底数k都是相同的,所以⾃然要想到把他们的指数分离出来~~。

例如这样然后把指数分离出来:0,1,0+1,2,0+2,1+2,0+1+2,3....这时候看可能没什么头绪,但是再看⼀遍题⽬,你会发现题⽬中强调了两个字qwq——————— 递增。

也就是说我们在确定第n项时,要从之前确定的n-1项中选出⼀项:⼤于第n-1项但是⼩于⽬前能⽣成的任意⼀项,所以很容易想到:每确⽴⼀个数,就从数列的第⼀项开始逐个加上这⼀项,就造成了递增的效果。

但是这样做还有很⼤的缺陷,因为在前n-1项中,难免会有重复的项,举个最简单的例⼦:0,1,0+1,2,0+2,1+2;如果确⽴了第三项(0+1)的时候,对前⾯2项进⾏加法操作,明显会造成重复,并且不符合题⽬要求(递增和互不相等的⽅幂)。

那么这个算法就要进⾏改进。

在这⾥定义⼀下:单独数:就是不是由加法操作得到的数(k的n次⽅那种qwq)合成数:由单独数+合成数或由合成数+合成数组成的数所以对于每⼀个合成数都有单独数的参与,我们想,可不可以先预处理出k的1-n次⽅,显然⼀个快速幂就可以了,那么再想想,如果每读⼊到⼀个单独数,就可以⽤这个单独数按照刚才的⽅式来得到后⾯的n-1项。

经过验证显然是可以的。

如样例:k=3,n=100时:⽤f[i]代表第i项,有:令v=每⼀个单独数f[i]f[++i]=k(1 to n) v+f[k]⾄此这个题⽬的分析就好了.....下⾯是代码~#include<bits/stdc++.h>#define re register#define ull unsigned long longusing namespace std;int k,n,p;ull a[1000],f[2000000];inline int read() //读⼊优化{int k=1;int sum=0;char c=getchar();for(;'0'>c || c>'9';c=getchar())if(c == '-') k = -1;for(; '0' <= c && c <= '9'; c = getchar())sum = sum * 10 + c - '0';return sum * k;}inline void out(int x) //输出优化{if(x < 0) { putchar('-'); x *= -1; }if(x > 9) out(x / 10);putchar(x % 10 + '0');}inline ull quick_pow(int r,int k) //快速幂{ull base=r,ans=1;while(k!=0){if(k&1) ans=ans*base;base=base*base;k/=2;}return ans;}int main(){//freopen("sequence.in","r",stdin);//freopen("sequence.out","w",stdout);k=read();n=read();a[0]=1;a[1]=k;for(re int i=2;i<=n;i++) a[i]=quick_pow(k,i); //预处理k的1-n(保险)次幂for(re int i=1;i<=n;i++){f[i]=a[p];p++; //对于每⼀个单独数的赋值ull tmp=f[i]; //记录v值(单独数)int h=i; //确⽴i-1项(避免后来i的更新)if(i>1){{for(re int j=1;j<h;j++) {f[++i]=tmp+f[j];if(i>=n){cout<<f[n]; //输出 return 0;}}}}out(f[n]);return 0;}。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
using namespace std; int s[30001]; int main(int argc, char *argv[]) {
int i, j, n, m, v, w; cin >> n >> m; for ( i = 0 ; i < m ; i++ ) {
cin >> v >> w; for ( j = n ; j >= v ; j-- )
注 : 本 份 解 题 报 告 的 参 考 答 案 均 采 用 G++ 编 译 器 通 过 , 并 已 经 在 /JudgeOnline中测试通过,欢迎大家在在线测评中提交检测,如遇到
问题可到:北京市科协网站的在线交流(/bjnoi/)或到作者的交流 论坛的相应板块中提交。输入输出形式,采用的均为标准输入输出, 如果需要针对竞赛,请更改为相应的文件操作即可。
if (st[i] != z[t - (w - 1) + i]) {
f = false; break; } if ( f ) return; i= 0; while (st[w - i - 1] == z[t - i]) i++; st[w - i - 1]++; c = st[w - i - 1]; for (x = 1 , j = w - i ; j < w ; j++ , x++) st[j] = c + x; } int main(int argc, char *argv[]) { char st[28] , *str; char str1[28]; int i, j, k; cin >> s >> t >> w; cin >> st; str = st; for ( i = 0 ; i < 5 ; i++ ) { strcpy(str1 , str); pre(str); if ( strcmp(str1 , str) != 0) cout << str << endl; else break; } //system("PAUSE"); return EXIT_SUCCESS; } 四、数列 没有想到最后一道题会这么简单,看到题目以后,看到数列首先有些困惑,但是,括 号里的内容,却让思路豁然开朗。这个表达式,明显的表现出了,加法算式的部分选择,这 种情况很正常的想到了 2 进制的 01 转化后和加法算式部分的乘积后的结果。而且,仔细观 察在这道题目中,我们甚至不用生成 2 进制的 01 形式,只需要将 N 转化成为 2 进制就可以 了。可以说,真的是不能够再简单了。
using namespace std; int s[1001] , x[1001]; int main(int argc, char *argv[]) {
int i, t, n; cin >> n; while (n--) {
cin >> t; s[t]++; } for ( t = 0 , i = 0 ; i <= 1000 ; i++ ) if (s[i])
x[t++] = i; cout << t << endl; cout << x[0]; for ( i = 1 ; i < t ; i++ )
cout << " " << x[i];
cout << endl; //system("PAUSE"); return EXIT_SUCCESS; } 二、开心的金明 在 2005 年,大家熟悉了“采药”后,应该说这道题,是一道送分题目。分析也很简单, 用消耗的 N 元钱,来换价值和重要度的乘积。而结构上,属于明显的 01 背包问题。 参考程序如下: #include <cstdlib> #include <iostream>
参考程序如下: #include <cstdlib> #include <iostream>
using namespace std; int s[33]; int kf(int k, int x) {
int i, s; s = 1; for ( i = 0 ; i < x ; i++ )
s *= k; return s; } int main(int argc, char *argv[]) { int k, n, i, w; int t; cin >> k >> n; w = 0; while ( n != 0 ) {
using namespace std; char z[28] = "0abcdefghijklmnopqrstuvwxyz"; int s, t, w; void pre(char *st) {
char c;
int i, j, x; bool f; f = true; for (i = w - 1; i >= 0 ; i-- )
下面,我们来分别看一看各个题目。 一、明明的随机数 在这道题中,再次考察了 2005 年中校门外的树的一一对应的哈希表的知识点,当然, 对待数的排序来说,更是简化了的“箱排序”思想。用至少有 1000 个数组元素的数组,用 位置和数值,一一对应。用位置代替数值。每得到一个数值就在数组的相应位置上做一个标 记或者做加。这样,从头到尾统计一下数值非零的位置就知道有多少个不相同的数字了。可 以然后再记录下来这些数字,从头到尾输出即可。当然,本题因为是要输出个数,并且个数 要求在前,所以需要从头儿到尾统计一下个数。 参考程序: #include <cstdlib> #include <iostream>
if (s[j - v] + v * w > s[j] ) s[j] = s[j - v] + v * w;
} cout << s[n] << endl; //system("PAUSE"); return EXIT_SUCCESS; } 三、Jam 的计数法 这道题在整套题中,属于最难的一题了。也是一道单纯的字符串题目。这道题,一般 会给人一种错觉,好似是回溯的题目去查找,但如果仔细分析,其实题目非常简单。就是要 从后面查找可以改变的位置。如果没有可以改变的了,就代表后面没有数字了。如果有可以 改变的,则这个字母可以做加 1 的操作,而这个可以改变的位置后面的所有字母均需要变的 跟改变的字母连续变化即可。只要把握好这两点,题目可以非常简单的解决。 参考程序如下: #include <cstdlib> #include <iostream>
s[w] = n % 2; n /= 2; w++; } /* for ( i = 0 ; i < w ; i++ ) cout << s[i]; cout << endl; */ t = 0; for ( i = 0 ; i < w ; i++ ) { t = t + s[i] * kf(k , i); } cout << t << endl; //system("PAUSE"); return EXIT_SUCCESS; }NOIP 2006 年普及组解报告北京市八一中学 王祺磊
2006 年,普及组的题目出的略显简单,和提高组题目形成鲜明对比。但是,题目考察 面全面而有效,李老师的程序功底可见一斑。
题目上来说,主要考察了几个方面:模拟(主要是一一对应的哈希表使用),动态规划 (继续了 2005 年的背包问题),字符串操作(规则简单,难度不深),取值规律(简化了的 2 进制全模拟取舍)。其实说简单,主要因为 2005 年普及组的采药刚刚出了 01 背包,在本 年中又出了一道,让人突出的感觉到了 01 背包的重要,也为信息学的动态规划时代,拉开 了序幕。从 2006 年起,动态规划就成了信息学教学的重中之重。而最后一题的规律过于简 单,而且,去掉了,生成所有情况的较复杂部分,只保留了 2 进制转换后的部分。考察点显 得有些过于直白了。
相关文档
最新文档