核电站问题转载自saltless原创

Rqnoj105 核电站问题 题解

      又回到我可爱的Blog了~昨天偷了点懒,一篇文章也没写~今天一定抽时间补上。

      下面切入正题。

 

 

【题目描述】(rqnoj105)
一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数
 
【输入格式】
输入文件只一行,两个正整数N,M( 1<N<50,2≤M≤5)
 
【输出格式】
输出文件只有一个正整数S,表示方案总数。
 
【样例输入】
4 3
 
【样例输出】
13

 

 

      这是一道线性递推类的动态规划。说实话,这道题我直接看的题解,竟然没有看懂,纠结我一节课…先把代码贴上:

 

 

复制代码
    
    
1 program nuclear; 2 var 3 f: array [ - 6 .. 60 ] of int64; 4 i,m,n:integer; 5 begin 6 readln(n,m); 7 f[ 0 ]: = 1 ; 8 f[ - 1 ]: = 1 ; 9 for i: = 1 to n do 10 f[i]: = 2 * f[i - 1 ] - f[i - m - 1 ]; 11 writeln(f[n]); 12 end .  
复制代码

 

 

      这巨短的代码理解起来还真不容易。首先,f数组存储的是到第f个坑可能出现的情况数。网上很多题解都用到分情况讨论,根据Jingo大牛的无敌思想,只要把数组向前多定m位,即-m到n即可。

      另外一个比较纠结的地方就是这个神奇的动态方程。你可以自己分析一下,如果不懂请看下文。

      我们先将方程分解,即f[i]:=f[i-1]+f[i-1]-f[i-m-1],这是显而易见的。两个f[i-1]分别代表的是f[i]位上放或者不放。但是f[i]上能放的条件是连续的一排上最多有m-1堆。以样例为例,当i=4时有以下状态:

 

 

 

 

 

      因为如果在(4)放,在(3)号坑放的前提下(2)一定是不放的。所以要用在f[i-1](3号坑放的那一个)中排除有(2)且有(3)的那种情况。

      由题意可知,如果(2)(3)都有核物质,(1)中一定没有。所以能达到图中的的状态的情况数只等于f[0],即f[i-m-1]的值。这时f[i-1]-f[i-m-1]就好理解了。

      还有一个问题就是为什么f[0]和f[-1]都初始化为1。这可以从上文很简单的找到答案。因为当i=m(i-m-1=-1)或i=m+1(i-m-1=0)时,需要减去i,i-1,…,i-m+1都有核物质的这一种不符合题意的情况。

      现在请把鼠标滚轮向上滚,重新看一遍代码。这是你就可以体会到这段伟大的O(n)的DP代码的魅力了。

 

(saltless原创,转载请注明出处)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值