牛客--64--F

关键

这个题目很值得学习呀!
看着是不能记录所有的状态,但是可以映射一下,然后就是直接线性dp了

代码

#include <bits/stdc++.h>
using namespace std;
const int M=2e6+5;
const int mod=998244353;
using pii=pair<int,int>;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}

void add(int &x,int y) {
    x=(x+y)%mod;
}

bool g[M][4];
int f[M][4];
unordered_map<int,int>mp;
vector<int>v;
vector<pii>node;

int main() {
    int n=read(),m=read();
    while(m--) {
        int x=read(),y=read();
        v.push_back(y);
        v.push_back(y+1);
        v.push_back(min(n,y+2));
        node.push_back({x,y});
    }
    v.push_back(1);
    v.push_back(n);
    sort(v.begin(),v.end());
    int len=v.erase(unique(v.begin(),v.end()),v.end())-v.begin();
    for(int i=0;i<len;i++)mp[v[i]]=i+1;
    for(auto [x,y]:node)g[mp[y]][x]=1;
    f[1][1]=1;
    //for(auto [x,y]:mp)cout<<x<<' '<<y<<endl;
    for(int i=1;i<len;i++) {
        for(int j=1;j<=3;j++) {
            if(g[i][j]) {
                //cout<<i<<' '<<j<<endl;
                add(f[min(i+2,len)][j],f[i][j]);
                add(f[i+1][max(1,j-1)],f[i][j]);
                add(f[i+1][min(3,j+1)],f[i][j]);
            }
            else add(f[i+1][j],f[i][j]);
        }
        //cout<<f[i][1]<<' '<<f[i][2]<<' '<<f[i][3]<<endl;
    }
    for(int i=1;i<=3;i++)cout<<f[len][i]<<'\n';
    return 0;
}
posted @ 2022-12-30 22:00  basicecho  阅读(28)  评论(0)    收藏  举报