传送门:cf 478d
给定红绿两种砖块,问搭成的塔层数最高的情况下一共有多少种不同的情况,每一层的颜色必须相同。塔自上向下每层块数为1,2,3,4……
dp,首先通过两种砖块的和求出最高的层数。dp[i][j]表示i层用j块红砖的情况数,转移方程
dp[i][j]=(dp[i][j]+dp[k][j-i])(0<=k<=i-1)
需要用到的是所有j+g>=(n层块数)的j
/******************************************************
* File Name: d.cpp
* Author: kojimai
* Create Time: 2014年10月24日 星期五 15时38分37秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define FFF 200005
#define mod 1000000007
int f[FFF];
int findn(int x) {
int l = 1, r = 1000, mid;
while(l <= r) {
mid = (l + r) >> 1;
if((mid * (mid + 1) / 2)>x)
r = mid - 1;
else
l = mid + 1;
}
return r;
}
int main()
{
int r,g;
cin>>r>>g;
int n = findn(r + g);//找出最高的层数
memset(f,0,sizeof(f));
f[0] = 1;
for(int i = 1; i <= n; i++) {//加上了第i层之后求红块用了j块一共有多少种情况
for(int j = r; j >= i; j--) {
f[j] += f[j-i]; //当前层用了j,i-1层需要j-i块
if(f[j] >= mod)
f[j] -= mod;
}
}
int ans = 0;
for(int j = r; j + g >= n*(n+1)/2 && j >= 0; j--) {
ans += f[j];
ans %= mod;
}
cout<<ans<<endl;
return 0;
}