Fabricating Sculptures dp+前缀和优化

62 篇文章 0 订阅

题目链接: https://codeforces.com/gym/102428/problem/F

题意:

你现在有 m m m 个方块,要搭建一个以 s s s 为底的一个模型,这个模型是不能储水的结构,即不存在一列,其左边和右边的俩均比它高,问你有多少种搭建的方法。

做法:

d p [ i ] [ j ] dp[i][j] dp[i][j] 表示以 i i i 为底的时候,还有 j j j 个方块时的方案数。这个时候 d p [ i ] [ j ] = 1 ∗ d p [ i ] [ j − i ] + 2 ∗ d p [ i − 1 ] [ j − i + 1 ] + 3 ∗ d p [ i − 2 ] [ j − i + 2 ] . . . dp[i][j]=1*dp[i][j-i]+2*dp[i-1][j-i+1]+3*dp[i-2][j-i+2]... dp[i][j]=1dp[i][ji]+2dp[i1][ji+1]+3dp[i2][ji+2]... ,这个式子很容易得出,但是在原来我们做的时候,用记忆化搜索对于每一个 d p [ i ] [ j ] dp[i][j] dp[i][j] f o r for for 了一次所有的情况,所以就 T T T 了,这个结构我们可以发现是 可以用两个前缀和来维护的,一个维护 s u m [ i + j ] sum[i+j] sum[i+j] 的前缀和,另一个维护上面那样,所谓前缀和的前缀和。

代码

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

typedef long long ll;
const int maxn=5005;
const int mod=(int)1e9+7;
int n,m;
ll sum[maxn*2],psum[maxn*2],dp[maxn][maxn];
int main() {
    scanf("%d%d",&n,&m);
    m-=n;
    for(int s=1;s<=n;s++){
        for(int res=0;res<=m;res++){
            psum[res]=(psum[res]+sum[res])%mod;
            if(res==0) dp[s][res]=1;
            else  dp[s][res]=(dp[s][res]+psum[res])%mod;
            sum[s+res]=(sum[s+res]+dp[s][res])%mod;
        }
    }
    printf("%lld\n",dp[n][m]);
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值