cf#273-D. Red-Green Towers-dp

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


题意:给你r个红砖,g个绿砖

让你建成 一个塔,每一层需要的砖块数为 1 2 3 4 ...n

每一层必须同色

假设最高能搞成的塔为h,求建造高度为h的塔的方案数


h=sqrt(2.0*(r+g));

while(h*(h+1)>2*(r+g)) h--; 得到高度h


然后就是dp, 当前一层需要need块砖

if (红砖够)  ;  dp[i][j+need]+=dp[i-1][j];

if (绿砖够)    dp[i][j] += dp[i-1][j];


然后改成滚动数组即可

【注意初始化条件。。我就是漏了第二句初始化才wa。。。】

if (r>=n)

dp [1][n]=1;

if (g>=n) //绿砖不要漏。。

dp [1][0]=1;


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001; 
int min(int a,int b)
{return   a<b?a:b;} 
int max(int a,int b)
{return a>b?a:b;}
int dp [2][2*100005];
int mod=1e9+7;
int main()
{	
	int i,j;
	int r,g;
	cin>>r>>g;
	int n=sqrt(2.0*(r+g));
	while(n*(n+1)>2*(r+g)) n--;
//	memset(dp,-1,sizeof dp);
	if (r>=n)
		dp [1][n]=1;
	if (g>=n)
		dp [1][0]=1;
	
	for (i=1;i<n;i++)
	{
		int need= n-i+1 -1;
		int tol_last=(n+need)*(1+i)/2-need;
		for (j=0;j<=r;j++) dp[(i+1)%2][j]=0;
		for (j=0;j<=r;j++)
		{
			if (dp[i%2][j]==0) continue;
			if (g-tol_last+j>=need)
			{
				 
				{dp[(i+1)%2][j]+=dp[i%2][j];dp[(i+1)%2][j]%=mod;}
				
			}
			if (r-j>=need)
			{
			 
				{dp[(i+1)%2][j+need]+=dp[i%2][j];dp[(i+1)%2][j+need]%=mod;}
			}
		}
	}
	
	int sum=0;
	for(i=0;i<=r;i++)
		if (dp[n%2][i]!=0) {sum+=dp[n%2][i];sum%=mod;}
	printf("%d\n",sum);
	
	return 0; 
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值