zoukankan      html  css  js  c++  java
  • cf 1160 E dp 组合数 思维

    题意:给定一个数组,如果它含有长度>=3的回文数组,那就是不好的

      问通过将数组中的 -1 用【1,k】替代,有多少种可能,使这个数组是好数组。

    思路:长度>=3的回文数组,都可以转化为==3的来看,所以整个数组不含有==3的回文数组

      也就是a[i]!=a[i+2] (  a[i]!=-1)

    这样就可以奇偶分开来看了,将两者的组合撑起来就是答案

    那么对形如   x..-1-1-1y..-1.z的序列,怎么判断可能呢?

    分段来看就有4种可能:  -1..-1   -1....a (a...-1)    a.-1...a   a..-1...b

    我们对后两种dp来做,d1[N][3]有三个状态  0 :a, 1 : b, 2 非a,b

    这样就有了dp的思路 了

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(v) v.begin(),v.end()
    #define mem(a) memset(a,0,sizeof(a))
    #define bug printf("get 
    ");
    const int N = 2e5+4;
    const ll mod =998244353;
    const int INF = 1e9+4;
    const double eps = 1e-7;
    
    int n,k;
    vector<int>arr;
    int a[N];
    ll ans1,ans2;
    ll d1[N][3],d2[N][2];//d1 : a....b d2 a...a
    ll d3[N];
    
    ll add(ll a,ll b){    return (a+b)%mod;}
    
    ll sol(){
        for(int i=0;i+1<arr.size();++i)if(arr[i]!=-1 &&arr[i]==arr[i+1])return 0;
        int anot=0;
        for(auto x:arr)if(x!=-1)anot++;
        if(anot==0){
            ll res=k;
            for(int i=0;i+1<arr.size();++i){
                res =res*(k-1)%mod;
            }return res;
        }
        //printf("??");
        arr.pb(0);int las= 0;
        ll res=1;
        for(int i=0;i<arr.size();){
            int num =0;
            while(arr[i]==-1){
                num++;
                i++;
            }
            if(num){
                //cout<<"num: " <<num<<endl;
                if(las==0 ||arr[i]==0){
                    res =res* d3[num]%mod;
                }
                else{
                    if(las==arr[i])
                        res= res * (d1[num][1]+d1[num][2])%mod;
                    else res = res * (d1[num][0]+d1[num][2])%mod;
                }
            }
            las= arr[i];
            i++;
        }
        //cout<<res<<endl;
        return res;
    }
    
    int main(){
        cin>>n>>k;
        d1[1][0] = 0;
        d1[1][1] = 1;//
        d1[1][2] = k-2;
        d2[1][0] = 0;//
        d2[1][1] =k-1;
        d3[1] = k-1;
        for(int i=2;i<=n;++i){
            d1[i][0] = add(d1[i-1][1],d1[i-1][2]);
            d1[i][1] = add(d1[i-1][0],d1[i-1][2]);
            //k==2???
            d1[i][2] = add( add(d1[i-1][0]*(k-2),d1[i-1][1]*(k-2))  ,d1[i-1][2]*(k-3));
            d2[i][0] = d2[i-1][1];// a
            d2[i][1] = add(d2[i-1][0]*(k-1) ,d2[i-1][1]*(k-2));//not a
            d3[i] = d3[i-1]*(k-1)%mod;
        }
    
        for(int i=1;i<=n;++i){cin>>a[i];}
        for(int i=1;i<=n;i+=2)
            arr.pb(a[i]);
        ans1=sol();
        arr.clear();
        for(int i=2;i<=n;i+=2)arr.pb(a[i]);
        ans2=sol();
    
       // printf("%lld %lld 
    ",ans1,ans2);
    
        cout<<ans1*ans2%mod<<endl;
        return 0;
    }
  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/10752930.html
Copyright © 2011-2022 走看看