随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述:

  有 n 张卡片,正面和反面各有一个数字,一开始全部正面朝上。

  你可以选择翻转一些卡片(也可以不反转),求出使每两张相邻的卡片上的数字都不相同的方案数。1<=n<=200000,答案对 998244353 取模。


二、做题思路:

  设:x[i]表示第 i 张卡片正面的数;
    y[i]表示第 i 张卡片反面的数;
    dp[i][1]表示在反转第 i 张卡片的情况下,1~i 所有卡片的方案总数;
    dp[i][0]表示不反转第 i 张卡片的情况下,1~i 所有卡片的方案总数。
  容易得出以下结论:
    if (x[i]!=x[i-1]) dp[i][0]+=dp[i-1][0];
    if (x[i]!=y[i-1]) dp[i][0]+=dp[i-1][1];
    if (y[i]!=x[i-1]) dp[i][1]+=dp[i-1][0];
    if (y[i]!=y[i-1]) dp[i][1]+=dp[i-1][1];
  答案即是 dp[n][0]+dp[n][1] 。注意取模。时间复杂度 O(n) 。


三、完整代码:

复制代码
 1 #include<iostream>
 2 #define N 200010
 3 #define mod 998244353
 4 using namespace std;
 5 int n,x[N],y[N],dp[N][2];
 6 int main()
 7 {
 8     cin>>n;
 9     dp[1][0]=dp[1][1]=1;
10     for(int i=1;i<=n;i++)
11     {
12         cin>>x[i]>>y[i];
13         if(x[i]!=x[i-1])    dp[i][0]+=dp[i-1][0];
14         if(x[i]!=y[i-1])    dp[i][0]+=dp[i-1][1];
15         if(y[i]!=x[i-1])    dp[i][1]+=dp[i-1][0];
16         if(y[i]!=y[i-1])    dp[i][1]+=dp[i-1][1];
17         dp[i][0]%=mod;dp[i][1]%=mod;
18     }
19     cout<<(dp[n][0]+dp[n][1])%mod<<'\n';
20     return 0;
21 }
复制代码

四、写题心得:

  因为基本上是自己想出来的,而且是头一次想出来有一点难度的动态规划题,所以非常兴奋哦!!!加油!!!

posted on   trh0630  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示