ABC 291 D - Flip Cards(状态机)

https://atcoder.jp/contests/abc291/tasks/abc291_d

题目大意:

n张卡片排成一行。每张卡片正面是数字ai,背面是数字bi。最初,所有的牌都处于正面状态。

随机翻转>=0张卡片。问这一列是否相邻中的数字都是不同的,是就可行,求出这样可行的方法数量(以998244353为模)。 
Sample Input 1 
Copy
3
1 2
4 2
3 4
Sample Output 1 
Copy
4

(一开始没有看到是相邻卡片不可相等的状态,知道是状态机,但是想半天都没有想出方案,一看佬儿的写法,嗷~我看错题了原来又hh)
【注意取模】

写法一

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=-1e18;
const LL N=2e5+10,M=4010;
const LL mod=998244353;
const double PI=3.1415926535;
#define endl '\n'
LL a[N][3],f[N][3];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        for(int i=1;i<=n;i++) //n张卡片,0表示正面状态,1表示反面状态
        {
            cin>>a[i][0]>>a[i][1];
        }
        f[1][0]=1; //第一张卡片的正面肯定算一种方案
        f[1][1]=1; //第一张卡片的反面也肯定算一种方案
        for(int i=2;i<=n;i++) //从第二张卡片开始
        {
            for(int j=0;j<=1;j++) //当前卡片的两种状态
            {
                for(int k=0;k<=1;k++) //前面一张卡片的两种状态
                {
                    if(a[i][j]!=a[i-1][k]) //如果这张卡片的数字和前面一张的不一样
                        f[i][j]=(f[i][j]+f[i-1][k])%mod; //那么就可以把前面的数量加起来
                }
            }
        }
        cout<<(f[n][0]+f[n][1])%mod<<endl; //最后的答案就是两种状态的总数和
    }
    return 0;
}

写法二

意思和写法一 一致,就不赘述咯~

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=-1e18;
const LL N=2e5+10,M=4010;
const LL mod=998244353;
const double PI=3.1415926535;
#define endl '\n'
LL a[N],b[N],f[N][3];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i]>>b[i];
        }
        f[1][0]=1;
        f[1][1]=1;
        for(int i=2;i<=n;i++)
        {
            if(a[i]!=a[i-1]) f[i][0]=(f[i][0]+f[i-1][0])%mod;
            if(a[i]!=b[i-1]) f[i][0]=(f[i][0]+f[i-1][1])%mod;
            if(b[i]!=a[i-1]) f[i][1]=(f[i][1]+f[i-1][0])%mod;
            if(b[i]!=b[i-1]) f[i][1]=(f[i][1]+f[i-1][1])%mod;
        }
        cout<<(f[n][0]+f[n][1])%mod<<endl;
    }
    return 0;
}
posted @ 2023-02-27 23:04  Vijurria  阅读(35)  评论(0编辑  收藏  举报