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


    题目链接

    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);
    	}
    }
    
    
  • 相关阅读:
    OpenMp之reduction求和
    C++中的字节对齐
    java mail邮件发送(带附件) 支持SSL
    linux下通过命令启动多个终端运行对应的命令和程序
    JAVA数组的定义及用法
    ThreadPoolExecutor使用介绍
    命令拷屏之程序分析
    java实现第五届蓝桥杯供水设施
    java实现第五届蓝桥杯供水设施
    java实现第五届蓝桥杯供水设施
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/10970726.html
Copyright © 2020-2023  润新知