URAL 1513. Lemon Tale 好多大数

dp[ i ][ j ]表示长度 i ,末尾连续 j 个L的方案数。

dp[ i ][ 0 ]  = sigma dp[ i - 1 ][ j ] (0 <= j && j <= min(i-1,m));

dp[ i ][ j ] = dp[ i-1 ][ j-1 ] ( j != 0 && j <= min(i,m));

这是最简单明了的递推式子,可是时间复杂度为o (n*m),显然难以胜任。

通过对式子观察,第 dp[ i ] 对于 dp[ i-1 ]只多了 dp[ i ][ 0 ]这一项,也就是说我们需要计算只有dp[ i ][0]这一项,且dp[ i ][ 0 ] = sigma dp[ i - 1 ][ j ] (0 <= j && j <= min(i-1,m));

显然我们可以用栈将整个dp[ ][ ] 优化成一维数组。

若 m == 0,初始栈只有一个元素 1,否则初始栈有两个元素1,1。

我们只有需要计算n-2次栈顶的 k = min(Top,m) 项和即可。Top为栈中的元素个数。

此时,时间复杂度为 o(n)。

因为有大数只能用Java来写了. . . . . .幸好没用到复杂的数据结构=,=

import java.math.BigInteger;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {  
        Scanner cin = new Scanner(System.in);  
        int n, m, t, i, j;
        
        n = cin.nextInt();   
        m = cin.nextInt();    
        
        BigInteger []dp = new BigInteger[10002];
        
        
        
        int con = 1,Top;
        
        dp[0] = BigInteger.ONE;
        
        BigInteger ans = BigInteger.ZERO;
        
        if(m >= 1)
        {
        	dp[1] = BigInteger.ONE;
        	Top = 2;
        	ans = ans.add(dp[0].add(dp[1]));
        }
        else
        {
        	Top = 1;
        	ans = ans.add(dp[0]);
        }
        
        dp[Top] = ans;
        
        Top++;
        
        for(i = 2;i <= n; ++i)
        {
        	if(con < m)
        	{
        		ans = ans.add(ans);
        		con++;
        	}
        	else
        	{
        		ans = ans.add(ans);
        		ans = ans.subtract(dp[Top-m-2]);
        	}
        	dp[Top] = ans;
    		Top++;
        }
        
        System.out.println(dp[Top-1]);
    }
}  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值