首页 > 其他分享 >ABC 291 D - Flip Cards(状态机)

ABC 291 D - Flip Cards(状态机)

时间:2023-02-27 23:11:23浏览次数:47  
标签:typedef ABC const 卡片 int LL cin 状态机 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;
}

标签:typedef,ABC,const,卡片,int,LL,cin,状态机,Cards
From: https://www.cnblogs.com/Vivian-0918/p/17162310.html

相关文章

  • Atcoder ABC 291
    AtcoderABC291D题意n张牌,每张牌两面都有数字,可以翻面,问有多少种情况使得这n张牌中每相邻两张牌表面上的数互不相同思路线性dp,每次比较当前位和上一位是否相同即可......
  • 题解:【ABC291F】Teleporter and Closed off
    题目链接给定一个\(n\)个点的图,每个点只向编号最多大于它\(m\)的点连单向边,求不经过\(2\simn\)中的一个点,\(1\ton\)的最短路。注意到\(m\)很小,这里给出两种......
  • ABC291
    ABCDE无意义题F考虑每个点只与其前后\(m\)个点相邻,所以去掉这个点及其相连的边只是对这\(2m\)个点有影响先预处理前后缀最短路,然后枚举前\(m\)个点与后\(m\)个......
  • ABC267D 题解
    前言题目传送门!更好的阅读体验?两篇题解的代码写得很复杂,我是没有想到。思路很显然对于一个点,它必定会进入一个循环节。如何判断它进入循环节了呢?当一个点被经过两次,......
  • ABC 250 D
    ABC250D题意求1到n范围内有以下性质的数的个数:\(x=p*q^3\),其中p和q都是质数,\(p<q\).\(1\leqn\leq10^{18}\)思路将\(10^6\)内的质数筛出来,这就是q的范围,然后这个......
  • DMotion - 基于DOTS的动画框架和状态机
    【博物纳新】专栏是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项......
  • 有穷状态机与正则语言
    自动机理论是计算理论中的一个重要的分支,其致力于建立抽象的计算模型来阐释计算,用抽象刻画出来的“计算机”来说明一些基本的计算问题,例如什么是可计算的(可计算性),计算的......
  • ABC 289 C - Coverage(dfs)
    半个多月没写题,连暴力dfs都忘记了,完蛋,烂菜地里了https://atcoder.jp/contests/abc289/tasks/abc289_c题目大意:给定一个N,M个集合,然后分别给出M个集合里面的数字个数......
  • ABC236 E
    ABC263E题意从一个大小为n的数组选一些数,选的限制是:对于\(1\leqi\leqn-1\),\(a_i\)或者\(a_{i+1}\)被选。问题1:求符合题意要求的选法中最大平均数问题2:求符合题......
  • 案例:判断字符串abcoefoxyozzopp中出现次数最多的字符,并统计其次数
        //1.案例:判断字符串abcoefoxyozzopp中出现次数最多的字符,并统计其次数    varstr='abcoefoxyozzopp';    varo={};    fo......