【日常小测】三进制计数

  • 本文为博主原创,未经许可不得转载

分析:

设f[i][j][k]表示最近的0在位置i,1在位置j,2在位置k

然后大力讨论当前位置上的数字进行转移就行了

考试时没有想到如何设置状态gg

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<bits/stdc++.h>
#define FILE "three"
using namespace std;
typedef pair<int,int> pii;
const int mod=1e9+7;
int n,m,ans,f[305][305][305];
vector<pii>Point[305];
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
inline int sub(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return 1LL*a*b%mod;}
bool check(int i,int j,int k){
int r=max(i,max(j,k));
for(int x=0;x<Point[r].size();++x){
int l=Point[r][x].first,c=Point[r][x].second;
c-=(i>=l)+(j>=l)+(k>=l);
if(c!=0) return 0;
}
return 1;
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read(); m=read();
for(int i=1;i<=m;++i){
int l=read(),r=read(),c=read();
Point[r].push_back(make_pair(l,c));
}
f[1][0][0]=f[0][1][0]=f[0][0][1]=1;
for(int i=1;i<=n;++i)for(int j=0;j<i;++j)for(int k=0;k<i;++k){
if(!check(i,j,k)) f[i][j][k]=0;
if(!check(j,i,k)) f[j][i][k]=0;
if(!check(j,k,i)) f[j][k][i]=0;
f[i+1][j][k]=add(f[i+1][j][k],f[i][j][k]);
f[i][i+1][k]=add(f[i][i+1][k],f[i][j][k]);
f[i][j][i+1]=add(f[i][j][i+1],f[i][j][k]);
f[j][i+1][k]=add(f[j][i+1][k],f[j][i][k]);
f[i+1][i][k]=add(f[i+1][i][k],f[j][i][k]);
f[j][i][i+1]=add(f[j][i][i+1],f[j][i][k]);
f[j][k][i+1]=add(f[j][k][i+1],f[j][k][i]);
f[j][i+1][i]=add(f[j][i+1][i],f[j][k][i]);
f[i+1][k][i]=add(f[i+1][k][i],f[j][k][i]);
}
for(int j=0;j<n;++j)for(int k=0;k<n;++k){
ans=add(ans,f[n][j][k]);
ans=add(ans,f[j][n][k]);
ans=add(ans,f[j][k][n]);
}
printf("%d\n",ans);
return 0;
}
文章目录
,