cf909C 线性dp+滚动数组好题!

一开始一直以为是区间dp。。

/*
f下面必须有一个s
其余的s可以和任意f进行匹配 
所以用线性dp来做
先预处理一下: 
fffssfsfs==>3 0 1 1 
dp[i][j] 表示第i行缩进到j的方案数 
那么 dp[i][j]=sum(dp[i-1][j-len...5000])
*/
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
#define maxn 10005
int n,m,dp[maxn],len[maxn];
int main(){
    cin>>n;char ch;int tmp=0;
    for(int i=1;i<=n;i++){
        cin>>ch;
        if(ch=='f')tmp++;
        else len[++m]=tmp,tmp=0;
    }
    memset(dp,0,sizeof dp);
    dp[0]=1;
    for(int i=1;i<=m;i++){
        for(int j=5000;j>=0;j--)
            dp[j]=(dp[j]+dp[j+1])%mod;
        for(int j=5000;j>=0;j--)
            if(j>=len[i])dp[j]=dp[j-len[i]]; 
            else dp[j]=0;
    }
    ll ans=0;
    for(int i=0;i<=n;i++)
        ans=(ans+dp[i])%mod;
    cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/10665534.html