因为构建到第i层时所需砖块总数是一定的,所以我们只需要考虑构建到第i层时用了多少块红砖,到最后将符合条件的情况相加即可。令DP[i][j]表示构建到第i层,且此时使用了j个红色砖块,那么DP[i][j]=DP[i-1][j-i],滚动数组实现即可,循环完成后只需将所有满足h*(h+1)-i<g条件的相加即可。
#include <iostream>
using namespace std;
long long dp[200010]={1};
const long long MOD=1000000007;
int main()
{
int r,g;
cin>>r>>g;
int h=1,sum=(r+g)<<1;
while((h*(h+1))<=sum) h++;
h--;
sum=0;
for(int i=1;i<=h;i++)//i表示层数,滚动数组
for(int j=r;j>=i;j--) dp[j]=(dp[j]+dp[j-i])%MOD;
sum=(h*(h+1))>>1;
if((sum-g)<0) sum=0;
else sum-=g;//一定要判断sum取值是否小于0 1 100000
long long ans=0;
for(int i=sum;i<=r;i++)
ans=(ans+dp[i])%MOD;//将所有可能情况相加
cout<<ans<<endl;
return 0;
}