ABC215 E - Chain Contestant(状压dp)
Posted live4m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABC215 E - Chain Contestant(状压dp)相关的知识,希望对你有一定的参考价值。
题意:
解法:
状压dp,
令d[i][j][k]表示前i个人,当前已经用的数的集合为j,末尾为k的方案数.
其中j=[0,(1<<10)),k=[0,10).
对于当前状态d[i][j][k],
1.如果下一个数s[i+1]满足k==s[i+1]||!(j&(1<<s[i+1])),那么可以接在后面,
此时d[i+1][j|(1<<s[i+1])][s[i+1]]+=d[i][j][k].
2.s[i+1]单独作为开头,
此时d[i+1][(1<<s[i+1])][s[i+1]]+=1.
code:
#include<bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=1e5+5;
const int mod=998244353;
int d[1005][(1<<10)][10];
char s[maxm];
int n;
void solve(){
cin>>n;
cin>>(s+1);
for(int i=1;i<=n;i++){
s[i]-='A';
}
for(int i=0;i<n;i++){
d[i+1][(1<<s[i+1])][s[i+1]]=(d[i+1][(1<<s[i+1])][s[i+1]]+1)%mod;//单独
for(int j=1;j<(1<<10);j++){//已经用了的集合
for(int k=0;k<10;k++){//序列最后一个数
if(!d[i][j][k])continue;
d[i+1][j][k]=(d[i+1][j][k]+d[i][j][k])%mod;//不接在后面
if(k==s[i+1]||!(j&(1<<s[i+1]))){//接在后面
d[i+1][j|(1<<s[i+1])][s[i+1]]=(d[i+1][j|(1<<s[i+1])][s[i+1]]+d[i][j][k])%mod;
}
}
}
}
int ans=0;
for(int j=1;j<(1<<10);j++){
for(int k=0;k<10;k++){
ans=(ans+d[n][j][k])%mod;
}
}
cout<<ans<<endl;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}
以上是关于ABC215 E - Chain Contestant(状压dp)的主要内容,如果未能解决你的问题,请参考以下文章