openjudge 9277 堆木头的解题报告

openjudge 9277 堆木头的解题报告。
DP-前缀和-优化。(重点)。
总时间限制: 1000ms 内存限制: 131072kB
描述
Daxinganling produces a lot of timber. Before loading onto trains, the timberjacks will place the logs to some place in the open air first. Looking from the sideway, the figure of a logs stack is as follows:
We have known that the number of logs in each layer is fewer than the lower layer for at least one log, and that in each layer the logs are connected in a line. In the figure above, there are 12 logs in the bottom layer of the stack. Now, given the number of logs in the bottom layer, the timberjacks want to know how many possible figures there may be.
给出在最底层的木头的个数,问有多少种堆放木头的方式,当然你的堆放方式不能让木头掉下来.
在堆放的时候木头必须互相挨着在一起.

输入
The first line of input contains the number of test cases T (1 <= T <= 1000000). Then T lines follow. Every line only contains a number n (1 <= n <= 200000) representing the number of logs in the bottom layer.

输出
For each test case in the input, you should output the corresponding number of possible figures. Because the number may be very large, just output the number mod 10^5.
样例输入
4
1
2
3
5
样例输出
1
2
5
34
提示
当输入3时,有5种方式
第一种:上面一个也不放
第二种:上面放一根,放在最左边
第三种:上面放一根,放在最右边
第四种:上面放二根
第五种:上面先放二根,然后在二根的上面放一根

这是一道很显然的动态规划的题,理解题意,这个题还是不是很刁难,因为所有的木头要求是必须连在一起,所以这个递推出来就很简单了,只需要考虑放的位置和组合的大小就没必要再考虑什么同一层有不同的组合。
like 你在最底层有5个的时候有4个空,而这个时候就不需要最左边的空考虑放什么,最右边的空放不放的问题。直接就是通过上一层的进行递推,而且,就只用考虑i-1层的摆放问题就好,组合就不用考虑。
举个栗子,这道题,底层为5,而作为倒数第二层就放1,那就4种方法,而如果就放2个,那那就有f[2]*3种方法,依次递推,这就是递推的伟大之处。
好了,献上状态转移方程。

嗯,还有标程。

 1 #include<cstdio>
 2 int f[200020];
 3 int main()
 4 {
 5     int t;
 6     f[1]=1;
 7     for(int i=2;i<=20;++i)
 8     {
 9     f[i]=1;
10     for(int j=1;j<=i-1;++j)
11     {
12         f[i]+=f[j]*(i-j);
13     }
14     }
15     scanf("%d",&t);
16     int a;
17     for(int i=1;i<=t;i++)
18     {
19     scanf("%d",&a);
20     int k=a;
21     printf("%d\n",f[a]);
22     }
23     return 0;
24 }

当然。如果你真的这么写。hhhhhh!!!当然不会过啊!肯定会超时啊!这样写就是个O(n^2)的算法。预处理就炸了。
所以。我们就得用点奇技淫巧。用动态前缀和来代替整个算法的过程。
而这个时候就得让我们更认真的研读这个状态转移方程(嗯,写的很装逼。)
f[i]=f[i-1]*1+f[i-2]*2+f[i-3]*3+.....+f[1]*(i-1)
f[i+1]=f[i]*1+f[i-1]*2+f[i-2]*3+.......+f[1]*i
发现他们的区别了吗!!发现了吗!!!没发现两式相减看看结果!嗯。每次发现都是多加了一组f[1]到f[i]。
好了!我们前缀和的方法,就是这个突破口。每次在动态维护数组f的时候,用一个动态的变量s来记录f[1]到f[i]的和。这样的话,就减去了很多重复的加法运算。
这种大数据量,就得认真的从优化入手。所有人都会想出状态转移方程,而问题。就是你。会不会优化了。
嗯。贴上程序。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int f[2000010];
 5 int main()
 6 {
 7     int n,t;
 8     f[1]=1;
 9     f[2]=2;
10     int s=1;
11     for(int i=3;i<=200000;++i)
12     {
13     s+=f[i-1];
14     s%=100000;
15     f[i]+=f[i-1]+s;
16     f[i]%=100000;
17     }
18     scanf("%d",&t);
19     for(int i=1;i<=t;i++)
20     {
21     scanf("%d",&n);
22     printf("%d\n",f[n]);
23     }
24     return 0;
25 }
时间: 2024-10-07 05:24:18

openjudge 9277 堆木头的解题报告的相关文章

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

uva 10881 Piotr&#39;s Ants 解题报告

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&page=show_problem&problem=1822 题目意思:有一条 L 厘米长的杆,上面有 n 只蚂蚁,给出每只蚂蚁的朝向以及离杆上最左端的距离,问 T 秒之后每只蚂蚁到达的位置,如果 T 秒后某个位置有多只蚂蚁同时到达,那么这堆蚂蚁处于的位置 + Turning,如果超过这条杆的长度,输出F

ZOJ Problem Set - 1025解题报告

ZOJ Problem Set - 1025 题目分类:动态规划 原题地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1025   题目大意就是有很多木头,都有各自的长度和重量.现在要加工这些木头,如果加工某根木头的长度和重量大于等于它上一根木头的长度和重量,那么加工它不需要时 间,否则要花1分钟.现给出一堆木头的长度和重量,要求加工完这堆木头可以花的最少时间.例如给出5根木头长度重量分别为(4,9), (5,2),

hdu 1514 Free Candies 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1514 题目意思:有4堆糖果,每堆糖果有n个,从上到下排好,取糖果只能从上往下取,取完的糖果放在篮子里,篮子里最多放5个,如果篮子里有两个颜色相同的糖果则可以取走放进口袋里,问最多能取走多少对糖果放进口袋.n<=40, 糖果颜色最多20种. 这题是抄这个人滴:http://fudq.blog.163.com/blog/static/1913502382014239225290/ 有些地方看得不太懂,本

常州培训 day3 解题报告

第一题: 给出数轴正半轴上N个点的坐标和其权值,给出初始体力值M,人一开始在位置0,体力值会随着走过路程的增加而增加,走多少个单位的路消耗多少体力值.到每个点可以打掉,消耗的体力值就是其权值.求 最多能打掉多少点. N<=10000,其他<=10^18; 解题过程: 1.一开始就直接想到是贪心,首先人是不可能往左走的,否则不会最优.枚举最后停在哪个点,减去到这个点需要的体力,然后把这个点之前的所有点(包括这个店)的权值排个序,从小到大一个一个打,打到体力没有为止.复杂度分析:枚举N次,每次快拍

济南-1029试题解题报告

By shenben 本解题报告解析均为100分解题思路. 上午 T1 题意:给你两个日期,问这两个日期差了多少毫秒 解析:标程用ctime库函数写的,编译器版本高了才会过(NOIP编译器版本不会太高): 只能老老实实打模拟. 小技巧:最后多输出“000”,计算秒就好了.(特判两个时间相同,只输出“0”) T2 题意:有m个站口,有n个人按顺序排队,求n+1个人最少等多长时间 解析:(标程显然 同下) ①n<m 输出0(显然) ②n>=m 建一个小根堆(可以用优先队列),把前m个人的时间扔到堆

JLOI2015 解题报告

那个嘛= =,虽说是JLOI的解题报告但还差第一题没写= =,就这样行啦 T2:[JLOI2015]城池攻占 首先这道题我们先考虑暴力,也就是每个点向父亲跑,我们考虑能否一起做,可以发现在同一个点的骑士可以用一个堆维护一起跳(因为没有改变优先级的操作)然后再用懒标记维护,我们可以直接用一个可合并堆来维护就可以啦 当然这道题用线段树,倍增都是可行的,就是空间比较拙计罢了,需要用一些奇奇怪怪的方法来干 CODE: 1 #include<cstdio> 2 #include<iostream&

均分纸牌(NOIP2000senior)解题报告

均分纸牌(NOIP2000senior) 解题报告 [题目描述] 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上:在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上:其他堆上取的纸牌,可以移到相邻左边或右边的堆上. 现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多. 例如 N=4,4 堆纸牌数分别为: ① 9 ② 8 ③

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的