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;
}