一、题目描述:
有 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 }
四、写题心得:
因为基本上是自己想出来的,而且是头一次想出来有一点难度的动态规划题,所以非常兴奋哦!!!加油!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】