惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
博客园 - Franky
罗磊的独立博客
G
Google Developers Blog
The GitHub Blog
The GitHub Blog
P
Proofpoint News Feed
Recent Announcements
Recent Announcements
V
V2EX
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
U
Unit 42
GbyAI
GbyAI
A
About on SuperTechFans
WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
D
DataBreaches.Net
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MongoDB | Blog
MongoDB | Blog

博客园 - Samson小天

My researches during my college life. 一些底层的简单东西。 IAT HOOK 实现进程保护 大年初一,总结一下去年的十大事件~ 解决多线程产生的“以前的函数求值超时,函数求值被禁用。必须继续执行才能重新启用函数求值” Guessing Game解题报告 (pku 2328) 数学之美 C# 自定义实体类或集合的自动排序 UltraRun is released 简单的QQ游戏中大家来找茬外挂编写思路 最近写C++程序时关于GetLastError的感悟。 在Vista的UAC下检查程序是否具有Admin权限及应用程序的权限切换 从程序开发角度谈类的封装性。 教你如何解决“线程间操作无效: 从不是创建控件的线程访问它” C#中调用WIN32的API 小记delegate,简单的委托介绍 一个计算简单数学表达式值的算法。 string类型的初值不是随便赋的,记一次奇怪的访问冲突事件 对C#中ADO.NET开发的理解
分析一道08年10月12日的江苏省程序设计大赛正赛题
Samson小天 · 2008-10-17 · via 博客园 - Samson小天

今年是我第一次参加省级的比赛,发来的通知上说是ACM ICPC江苏省区比赛,但是去了那边变成了大学生程序设计大赛,去掉一个I的差别可很大。不过虽然不是International,不过难度也不少。今天就先分析其中一道题目:

题目是英文的,这里我就把翻译好的给大家,翻译不好还请见谅

给出一个正整数n(1<=n<=2001)。在n的左边可以放置另外一个数m,这样就组成一个新数mn,其中m必须小于等于n的一半。如果还有一个整数k<=m/2,那么还可以继续组成一个新数kmn....

比如有一个数12,你就可以在这个数左边放1~6,组成112,212.....612,接下来212又可以继续分成1212。

在举一个例子n=8

第一轮产生:18,28,38,48

第二轮18:不能产生新数

第三轮28:128

第四轮38:138

第五轮48:148,248

第六轮128、138、148:不能产生新数

第七轮248:1248

第八轮1248:不能产生新数

Input:

输入一个数n

Output:

一共产生了多少数

 Input:

8

Output:

10

这道题目这一看之下有点像一个多叉树,第一次我想了一下,发现可以用递归做。因为我们可以看到当n=8时有4个新数,n=4时有2个新数,n=2时有一个新数,n=1时没有新数。代码如下:

递归法

递归的潜在效率损失的确很大,测100前还没有什么性能差别,但是测到400,500的时候和动态规划的性能差别已经很大了(这个是事后的测试了)。当时比赛提交以后被判为“超时”,这个结果已经是我料到的。当时浙江师范和复旦大学的队伍给了我很大的压力。好不容易清醒下来,重新看了下题目。想到一道北大上做过的题目“Function Run Fun”,这道题目一开始也是用递归做,结果超时,最后是用动态规划做出来的。

        仔细研究题目时候,发现

当n=0时有0个新数,

当n=1时1个新数,

当n=2时2个新数,

当n=3时2个新数,

当n=4时4个新数,

当n=5时4个新数,

当n=6时6个新数

当n=7时6个新数,

当n=8时10个新数。

    打表之后发现

n8=n1+n2+n3+n4+1=1+2+2+4+1=10

n7=n1+n2+n3+1=1+2+2+1=6

....

n4=n1+n2+1=1+2+1=4

     得到这个结论之后就能打表做了,开辟一个2002大小的double数组,初始化好之后直接访问就可以了。代码如下

动态规划法

     利用打表的方法是空间换速度,直接寻址的速度还是非常可观的,最后这道题终于AC了。