• 【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 }
  • 相关阅读:
    [ACM] hdu 1848 Fibonacci again and again(Nim博弈 SG函数)
    [ACM] hdu 2176 取(m堆)石子游戏(Nim博弈)
    [ACM] hdu 1850 Being a Good Boy in Spring Festival(Nim博弈)
    母函数
    Euclid算法(欧几里得算法)
    Poj 2533
    Poj 1836
    Poj 3267
    hdu 1878
    poj 3349
  • 原文地址:https://www.cnblogs.com/reddest/p/6003665.html
Copyright © 2020-2023  润新知