Codeforces Round 273 (Div 2 )D. Red-Green Towers dp+滚动优化

题目链接:

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

题意:

有红绿两色的方块,数量分别为r个和g个。有0<=r,g<=2e5,r+g>=1
我们想用这红绿两色的方块(不一定全部,可以是一部分),构成一个高度尽可能高的积木块。

这个积木块需要满足——
1,假设高度为h,那么第一层有1个,第二层有2个,……,第h层有h个。
2,每层方块的颜色,不是全部为红色,就是全部为绿色。

让你输出,有多少种方案,可以构成高度最高的积木块。

思路:

http://blog.csdn.net/snowy_smile/article/details/50266509

dp[i][j]:=摆成高度为i的,红块还有j个剩余 的方案数

转移:

 if(j+i<=r) dp[i][j] = dp[i][j]+dp[i-1][j+i]

 if(green >= i)  dp[i][j] = dp[i][j]+dp[i-1][j] : 如果剩下的绿块够摆第i层,可以不用红块,可转移

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define MS(a) memset(a,0,sizeof(a))
 5 #define MP make_pair
 6 #define PB push_back
 7 const int INF = 0x3f3f3f3f;
 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 9 inline ll read(){
10     ll x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 //////////////////////////////////////////////////////////////////////////
16 const int maxn = 2e5+10;
17 const int mod = 1e9+7;
18 
19 int r,g;
20 int dp[2][maxn];
21 
22 int main(){
23     cin >> r >> g;
24     int top = 900;
25     while(top*(top+1) > 2*(r+g)) top--;
26     int now = 0, pre = 1;
27     dp[now][r] = 1;
28     for(int i=1; i<=top; i++){
29         swap(now,pre);
30         MS(dp[now]);
31         for(int j=0; j<=r; j++){
32             if(j+i<=r) dp[now][j] = (dp[now][j]+dp[pre][j+i])%mod;
33             int t = g-((i-1)*i/2-(r-j));
34             if(t >= i) dp[now][j] = (dp[now][j]+dp[pre][j])%mod;
35         }
36     }
37     int ans = 0;
38     for(int i=0; i<=r; i++){
39         ans = (ans+dp[now][i])%mod;
40     }
41     cout << ans << endl;
42 
43     return 0;
44 }

 

 

posted @ 2017-05-24 14:26  _yxg123  阅读(159)  评论(0编辑  收藏  举报