JD23. 双色塔
描述
输入描述
输入仅包含两个正整数,分别表示红和绿砖块的数量a,b。输出描述
输出和仅包含一个正整数,表示不同的方案数对1000000007取模的结果。示例1
输入:
4 6
输出:
2
说明:
从底到顶颜色可以是 红、绿、红、绿 或 绿、绿、绿、红C++ 解法, 执行用时: 68ms, 内存消耗: 1912KB, 提交时间: 2021-05-13
// // Created by kumo on 2021/5/12. // #include <cstdio> #include <algorithm> #include <iostream> #define MOD 1000000007 using namespace std; int dp[2][200005] = {0}; int main() { int a, b; scanf("%d%d", &a, &b); if (a > b) { int c = a; a = b; b = c; } dp[0][1] = 1, dp[0][0] = 1; int total = 3; int least = max(total - b, 0); int most = min(total, a); int last = 0; int now = 1; int cur = 2; while (most >= least) { // cout << "most / least: " << most << " / " << least << endl; for (int i = 0; i < least; i++) { dp[now][i] = 0; } for (int i = least; i < cur; i++) { dp[now][i] = dp[last][i]; } for (int i = cur; i <= most; i++) { dp[now][i] = (dp[last][i - cur] + dp[last][i]) % MOD; // cout << "dp[0], dp[1], result: " << dp[now][i] << ", " << dp[last][i - cur] << ", " << dp[last][i] << endl; } cur++; total += cur; least = max(total - b, 0); most = min(total, a); last = 1 - last; now = 1 - now; } total -= cur; cur--; least = max(total - b, 0); most = min(total, a); int sum = 0; for (int i = least; i <= most; i++) { sum = (sum + dp[last][i]) % MOD; } cout << sum << endl; return 0; }
C++ 解法, 执行用时: 70ms, 内存消耗: 2716KB, 提交时间: 2021-07-02
#include<iostream> #include<vector> #include<math.h> using namespace std; #define MOD 1000000007 void GetCount(int a,int b) { if(a==0||b==0) { cout<<1<<endl; return; } //dp[i][j],i表示第i层,j表示石头个数,dp表示不同放置方式的个数 vector<vector<int>>dp(2,vector<int>(200000,0)); int level=sqrt(2*(a+b)); //假设红宝石个数最少 if(a>b) swap(a,b); int sum=1;//一共需要的石头个数 int upper,lower,cur,last; dp[1][0]=dp[1][1]=1; for(int i=2;i<=level;++i) { sum+=i; int redupper=min(a,sum);//红宝石的上限 //如果绿宝石b填补完前i层且sum-b>0,那么前i层至少需要sum-b个红宝石填充 int redlower=max(sum-b,0);//红宝石下限 if(redlower>redupper) break; upper=redupper; lower=redlower; cur=i&1; last=!cur; for(int j=lower;j<i;++j) { //由于前i层的红宝石个数少于 dp[cur][j]=dp[last][j]; } for(int j=i;j<=upper;++j) { dp[cur][j]= (dp[last][j] + dp[last][j - i]) % MOD; } } int res=0; for (int j = lower; j <= upper; j++) { res = (res + dp[cur][j]) % MOD; } cout << res << endl; } int main() { int a,b; cin>>a>>b; GetCount(a, b); return 0; }