【JZOJ4806】打工

来源:互联网 发布:java base64加密乱码 编辑:程序博客网 时间:2024/04/29 19:57

Description

这里写图片描述

Solution

不要看题目那么啰嗦,实际上一个合法序列的每个ai都要满足aimax(a1,,ai1)+1

然后我们就可以开始“愉快”的dp了。

Fi,j表示当前做到i,最大值为j

那么Fi,j可以从Fi1,j1+Fi1,jj转移过来,注意ai的边界即可。

Code

打的是很慢的方法,不同上面的。

#include<iostream>#include<cstdio>#include<cstdlib>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 10001#define mo 1000007#define ll long longusing namespace std;ll f[2][N][2];int a[N];int n;int main(){    freopen("1.in","r",stdin);    freopen("1.out","w",stdout);    cin>>n;    fo(i,1,n) scanf("%d",&a[i]);    f[1][1][1]=1;    int p=1,q=a[1];    fo(i,2,n)    {        p=1-p;        q=max(q,a[i]);        fo(j,1,i)        {            f[p][j][1]=0;            f[p][j][0]=(f[1-p][j][0]*max(0,j-a[i]+1)+(f[1-p][j][0]+f[1-p][j][1])*min(j,a[i]-1)+f[1-p][j-1][0])%mo;            if(j<a[i]) f[p][j][0]=f[p][j][0]+f[1-p][j-1][1];        }        f[p][q][1]=1;    }    ll ans=0;    fo(i,1,n) ans=(ans+f[p][i][0]+f[p][i][1])%mo;    cout<<ans;}
1 0
原创粉丝点击