CF1710C
数位DP入门题,给一种写起来很简洁的做法。
对于三个数
这三个式子是轮换的,先考虑第二个式子。
设
我们发现
所以我们可以在 DP 中多记三个量,分别表示目前能否保证
然后就写完了,时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int mod=998244353;
char a[N];
int n,dp[N][2][2][2][2][2][2];
inline int dfs(int k,bool l1,bool l2,bool l3,bool _x,bool _y,bool _z){
if(k>n)return _x&&_y&&_z;
if(dp[k][l1][l2][l3][_x][_y][_z]!=-1)return dp[k][l1][l2][l3][_x][_y][_z];
int res=0;
for(int x=0;x<=(l1?a[k]-'0':1);x++)for(int y=0;y<=(l2?a[k]-'0':1);y++)for(int z=0;z<=(l3?a[k]-'0':1);z++)
res=(res+dfs(k+1,l1&(x==a[k]-'0'),l2&(y==a[k]-'0'),l3&(z==a[k]-'0'),_x|(x==0&&y==1&&z==1)|(x==1&&y==0&&z==0),_y|(y==0&&x==1&&z==1)|(y==1&&x==0&&z==0),_z|(z==0&&x==1&&y==1)|(z==1&&x==0&&y==0)))%mod;
return dp[k][l1][l2][l3][_x][_y][_z]=res;
}
int main(){
scanf("%s",a+1);
n=strlen(a+1);
memset(dp,-1,sizeof dp);
printf("%d\n",dfs(1,1,1,1,0,0,0));
return 0;
}