Codeforces Round #518 (Div. 2) D(计数DP)

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
int n;
int a[100007];
long long dp[100007][207][3];//第i位值为j时k是否成立,k=0,i<i-1,k=1,i==i-1,k=2,i>i-1


int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=200;i++){
        if(a[1]!=-1&&a[1]!=i)
            dp[1][i][0]=0;
        else
            dp[1][i][0]=1;
        dp[1][i][1]=dp[1][i][2]=0;
    }
    long long sum=0;
    for(int i=2;i<=n;i++){
        sum=0;
        for(int x=1;x<=200;x++){
            if(a[i]!=-1&&a[i]!=x)
                dp[i][x][0]=0;
            else
                dp[i][x][0]=sum;
            sum+=(dp[i-1][x][0]+dp[i-1][x][1]+dp[i-1][x][2])%mod;
            sum%=mod;
        }
        for(int x=1;x<=200;x++){
            if(a[i]!=-1&&a[i]!=x)
                dp[i][x][1]=0;
            else
                dp[i][x][1]=(dp[i-1][x][0]+dp[i-1][x][1]+dp[i-1][x][2])%mod;
        }
        sum=0;
        for(int x=200;x>=1;x--){
            if(a[i]!=-1&&a[i]!=x)
                dp[i][x][2]=0;
            else
                dp[i][x][2]=sum;
            sum+=(dp[i-1][x][1]+dp[i-1][x][2])%mod;
            sum%=mod;
        }
    }
    long long ans=0;
    for(int i=1;i<=200;i++)
        ans+=(dp[n][i][1]+dp[n][i][2])%mod,ans%=mod;
    printf("%lld",ans);
    return 0;

}

原文地址:https://www.cnblogs.com/ldudxy/p/10030016.html

时间: 2024-08-05 14:30:56

Codeforces Round #518 (Div. 2) D(计数DP)的相关文章

Codeforces Round #139 (Div. 2)C Barcode DP

#include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 1010; const int inf = 0x3f3f3f3f ; int dp[maxn][2] ; char str[maxn][maxn] ; int num[maxn]; int sum_b[maxn]; int sum_w[maxn]; int main() { // fre

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

Codeforces Round #271 (Div. 2) D.Flowers DP

D. Flowers We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some red and white flowers. Therefore a dinner can be represented as a sequence of several

Codeforces Round #105 (Div. 2) D 概率DP

题目 呃 琢磨了半天还是琢磨出来了,题意有些模糊哈,有w个白色物品,b个黑色物品,A,B轮着抽,A先开始,谁先抽到白色谁赢,若最终都没有抽到白色 则算B赢,抽出来的物品不会放回去,B抽完以后 物品还会有一个额外产生丢失,问A赢的概率为多少 依旧是以目标状态为边界,当前状态到目标状态所需要的概率为 方程 dp[i][j] 代表当前轮到A抽的时候,还有i个白色的j个黑色的A赢的概率为多少 则当前转移可能有四种 1:A抽到了白色的,那么直接赢了,接下来不需要继续,所以没有与其它状态方程有联系 2:A抽

Codeforces Round #387 (Div. 2) 747F(数位DP)

题目大意 给出整数k和t,需要产生一个满足以下要求的第k个十六进制数 即十六进制数每一位上的数出现的次数不超过t 首先我们先这样考虑,如果给你了0~f每个数字可以使用的次数num[i],如何求长度为L且满足要求的十六进制数有多少个 dp[i][l]表示使用了前i个数字,已经将L的空位填上了l个的数有多少个 转移方程 dp[i][l] = sigma(dp[i-1][l-j]*C[len-l+j[j]) 其中j是枚举填新的数的个数,C是组合数(选出j个空位填上新数) 有了这个dp后,现在的问题就变

Codeforces Round #157 (Div. 1)B 数位dp

//枚举有几个(7或4),用数位dp的记忆化搜索找有i个(7或4)的数又多少个 //暴力搜索在第i个中选几个 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int mod = 1e9 + 7; int dp[20][20];//第i位有 j个数(7或者4) int bit[20] ; int temp[20]; int luck[20]; int dfs

Codeforces Round #168 (Div. 1)B 树形dp

//给一棵树,每次操作可以将包括顶点1的连通子集的所有点的节点加1或减1 //问最少几次操作使得这棵树的所有顶点的值都为0 //以1为根节点建树 //将加和减分开考虑,用up[u],down[u]表示以u为跟节点的子树中需要加的操作 //最大为up[u] ,需要减的操作最大为down[u] //其余的加和减的操作则可以在处理这两个操作时一起覆盖 //在将u的子数全都处理完后u点的值由于在加了up[u]和减了down[u]后变为 //一个新的值,则对于这个新的值根据它的正负并入up[u]或down

Codeforces Round #135 (Div. 2) D 树形dp

//任选一个根节点,用dfs搜两遍,第一遍找以该节点为根节点 //每一个节点的子树中的相反的边 //第二遍dfs以同样的根节点搜索一遍,记录从根节点到该节点 //正向边和反向边dp[u] = dp[root] - sum_0 + sum_1 : #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 200010 ; const int in

Codeforces Round #148 (Div. 1)C 树形dp

//枚举所有边,把该树分为两个树,分别求两颗数的最小的改变量 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 3030 ; const int inf = 0x7fffffff ; int dp[maxn] ; struct Edge { int flag , v; int u ; int next ; }edge[2*maxn] ;