码迷,mamicode.com
首页 > 其他好文 > 详细

[补题][Codeforces478D]Red-Green Towers(DP)

时间:2019-06-03 23:56:20      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:next   mat   public   string   固定   else   new   控制   左右   

题目链接

http://codeforces.com/problemset/problem/478/D

题意

叠放塔:有红、绿两种色块。从第一层开始,第一层1块,第二层2块,第i层i块。
要求每一层只能用同一种颜色的块。
输入:红块和绿块数目
输出;能叠放出的最高高度h的塔的种数。定义塔某一层的颜色不同,则为不同种。

题解

状态表示

dp[i][j]表示i层的塔,使用了j个红块

转移方程

dp[i][j]=dp[i-1][j]+dp[i-1][j-i],当j>=i
dp[i][j]=dp[i-1][j],当j<i

需要get的点

  • 根据给出的数据范围,最高只有900左右,找到h。 一定满足h可以搭出来怎么证?
  • dp只需要两维,因为当塔的高度h固定,则给出使用的红块数,则使用的绿块数=h-红块数。
  • 计算当前层块数时,控制红块至少大于等于总块数-已有绿块数,这样保证了绿块是够的。
  • 初始化:dp[0][0]=1即可 ?
  • 滚动数组否则爆内存

代码

package Exam;

import java.util.Scanner;

public class FirstTest {
    public static void main(String args[]) {
        Scanner in=new Scanner(System.in);
        int r=in.nextInt();
        int g=in.nextInt();
        
        int MAXH=(int) Math.floor(Math.sqrt(2*(r+g))) ;
        int MAXR=(int) 2e5;
        int MOD=(int)1e9+7;
        
        int h=MAXH;
        while(h*(h+1)/2>r+g) {
            --h;
        }
        
        int[][] dp=new int[2][MAXR];
        dp[0][0]=1;
        for(int i=1;i<=h;++i) {
            for(int j=0;j<=r;++j) {
                if(j-i>=0) {
                    dp[i&1][j]=((dp[(i-1)&1][j])%MOD+(dp[(i-1)&1][j-i])%MOD)%MOD;
                }
                else {
                    dp[i&1][j]=(dp[(i-1)&1][j])%MOD;
                }
            }
        }
        
        int ans=0;
        for(int i=Math.max(0,h*(h+1)/2-g);i<=r;++i) {
            ans+=dp[h&1][i];
        }
        System.out.println(ans);
    }
}

[补题][Codeforces478D]Red-Green Towers(DP)

标签:next   mat   public   string   固定   else   new   控制   左右   

原文地址:https://www.cnblogs.com/coding-gaga/p/10970726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!