• cf1000D Yet Another Problem On a Subsequence (dp)


    设f[i]是以i为开头的好子序列的个数

    那么有$f[i]=sumlimits_{j=i+a[i]+1}^{N+1}{f[j]*C_{j-i-1}^{a[i]}}$(设f[N+1]=1)就是以i为开头选出一个好子数组的每种情况*再把它拼到后面的一个好子序列的数量

    随便用什么方法预处理一下组合数就行了

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1e3+10,P=998244353;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 ll f[maxn],c[maxn][maxn];
    16 int a[maxn],N;
    17 
    18 int main(){
    19     int i,j,k;
    20     N=rd();
    21     for(i=1;i<=N;i++) a[i]=rd();
    22     
    23     c[1][0]=c[1][1]=1;
    24     for(i=2;i<=N;i++){
    25         for(j=0;j<=i;j++){
    26             if(j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
    27             else c[i][j]=1;
    28         }
    29     }
    30     
    31     for(i=N;i;i--){
    32         if(a[i]<=0||i+a[i]>N) continue;
    33         int s=0;
    34         for(j=N;j>=i+a[i]+1;j--){
    35             f[i]=(f[i]+c[j-i-1][a[i]]*f[j])%P;
    36         }
    37         f[i]=(f[i]+c[N-i][a[i]])%P;
    38     }
    39     ll ans=0;
    40     for(i=1;i<=N;i++) ans+=f[i],ans%=P;
    41     printf("%d
    ",ans);
    42     return 0;
    43 }
  • 相关阅读:
    2491 玉蟾宫
    1704 卡片游戏
    1020 孪生蜘蛛
    1215 迷宫
    3149 爱改名的小融 2
    1316 文化之旅 2012年NOIP全国联赛普及组
    1664 清凉冷水
    157. [USACO Nov07] 奶牛跨栏
    [SCOI2005]繁忙的都市
    【NOIP2014模拟赛No.1】我要的幸福
  • 原文地址:https://www.cnblogs.com/Ressed/p/9863311.html
Copyright © 2020-2023  润新知