zoukankan      html  css  js  c++  java
  • 【OpenJudge9277】【递推】Logs Stacking堆木头

    Logs Stacking堆木头

    总时间限制: 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

    【Solution】

      用dp[i]表示底层数为i的总方案数。

      我们可以发现,当底层数为i,上一层要放j个木头的时候,一共有(i-j)种情况。举个例子,当底层为5准备放2个木头时共有一下5-2=3种情况:

      所以我们可以得到一个状态转移方程式:dp[i]=dp[i-1]*(i-(i-1))+dp[i-2]*(i-(i-2))+...+dp[1]*(i-1)+1。这个转移方程可以理解为枚举所有可以往基层上一层放木头的可能性,把所有的可能方案相加。

      于是我就傻乎乎的N2算了一波,结果TLE(内心:这么性感的程序你还给我TLE???)。怎么优化到N呢?拿dp[4]和dp[5]做例子:

      dp[4]=dp[3]*1+dp[2]*2+dp[1]*3+1

      dp[5]=dp[4]*1+dp[3]*2+dp[2]*3+dp[1]*4+1

      注意红色的部分,我们发现dp[5]比dp[4]多了一个dp[1]+dp[2]+dp[3]+dp[4],我们会发现dp[i]比dp[i-1]多一个dp[1]+dp[2]+...+dp[i-1]。

    看到这里应该都能想到优化方案——用前缀和优化,这道题就A啦。

      AC代码:

      

     1 #include <cstdio>
     2 int T,N;
     3 int dp[200010],sum[200010];
     4 int main(){
     5     scanf("%d",&T);
     6     while(T--){
     7         scanf("%d",&N); dp[1]=sum[1]=1;
     8         for(int i=2;i<=N;++i){
     9             dp[i]=(dp[i-1]%100000+sum[i-1]%100000)%100000;
    10             sum[i]=(sum[i-1]%100000+dp[i]%100000)%100000;
    11         }
    12         printf("%d
    ",dp[N]%100000);
    13     }
    14     return 0;
    15 }
  • 相关阅读:
    rabbitmq在centos7下安装
    跨域问题
    11生成器相关及推导式(附内置函数分析图url)
    10函数名的应用,闭包,和迭代器
    09函数的动态传参及global和nonlocal关键字
    08函数简介
    07基本的文件操作
    06set集合和深浅拷贝(包括前面的一些知识点补充)
    05判断和编码/解码
    04基本数据类型(字典)
  • 原文地址:https://www.cnblogs.com/reddest/p/6003665.html
Copyright © 2011-2022 走看看