其实状态并不难想,就是设
f
[
i
]
[
S
]
f[i][S]
f[i][S]表示从
i
i
i位置开始后面连续
5
5
5个的移除状态为
S
S
S的最大高兴人数,然后预处理一个
g
[
i
]
[
S
]
g[i][S]
g[i][S]表示
i
i
i处开始后面连续
5
5
5个的移除状态为
S
S
S的高兴人数,于是就有转移式:
f
[
i
]
[
S
]
=
m
a
x
(
f
[
i
−
1
]
[
(
S
&
15
)
<
<
1
]
,
f
[
i
−
1
]
[
(
S
&
15
)
<
<
1
∣
1
]
)
+
g
[
i
]
[
S
]
f[i][S]=max(f[i-1][(S\&15)<<1],f[i-1][(S\&15)<<1|1])+g[i][S]
f[i][S]=max(f[i−1][(S&15)<<1],f[i−1][(S&15)<<1∣1])+g[i][S]
写的时候预处理那里写的有问题 w a wa wa了好几次我真是个 z z zz zz
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define maxn 10005
#define maxm 50005
using namespace std;
int n,m,f[maxn][(1<<5)+5],ed,ans,g[maxn][(1<<5)+5];
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}
int main(){
n=rd(); m=rd(); ed=1<<5;
for(int i=1;i<=m;i++){
int x=rd(),dl=0,lk=0;
int y=rd(),z=rd();
for(int j=1;j<=y;j++){
int aa=rd(); aa=(aa-x+n)%n;
dl|=(1<<aa);
}
for(int j=1;j<=z;j++){
int bb=rd(); bb=(bb-x+n)%n;
lk|=(1<<bb);
}
for(int j=0;j<ed;j++)
if((j&dl) || ((~j)&lk)) g[x][j]++;
}
for(int i=0;i<ed;i++){
memset(f[0],0xcf,sizeof f);
f[0][i]=0;
for(int j=1;j<=n;j++)
for(int k=0;k<ed;k++)
f[j][k]=max(f[j-1][(k&15)<<1],f[j-1][(k&15)<<1|1])+g[j][k];
ans=max(ans,f[n][i]);
}
printf("%d\n",ans);
return 0;
}
下面是我一开始的代码···又慢又麻烦 Q A Q QAQ QAQ
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define maxn 10005
#define maxm 50005
using namespace std;
int n,m,f[maxn][(1<<5)+5],ed,ans,g[maxn][(1<<5)+5];
vector<int> vec[maxn],a[maxm],b[maxm];
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}
inline void prework(){
for(int i=1;i<=n;i++)
for(int j=0;j<ed;j++){
for(int k=0;k<vec[i].size();k++){
int now=vec[i][k]; bool flg=false;
for(int x=0;x<a[now].size();x++)
if((1<<a[now][x])&j) {flg=true;break;}
for(int x=0;x<b[now].size();x++)
if(!((1<<b[now][x])&j)) {flg=true;break;}
if(flg) g[i][j]++;
}
}
}
int main(){
n=rd(); m=rd(); ed=1<<5;
for(int i=1;i<=m;i++){
int x=rd(); vec[x].push_back(i);
int y=rd(),z=rd();
for(int j=1;j<=y;j++){
int aa=rd(); aa=(aa-x+n)%n;
a[i].push_back(aa);
}
for(int j=1;j<=z;j++){
int bb=rd(); bb=(bb-x+n)%n;
b[i].push_back(bb);
}
}
prework();
for(int i=0;i<ed;i++){
memset(f[0],0xcf,sizeof f);
f[0][i]=0;
for(int j=1;j<=n;j++)
for(int k=0;k<ed;k++)
f[j][k]=max(f[j-1][(k&15)<<1],f[j-1][(k&15)<<1|1])+g[j][k];
ans=max(ans,f[n][i]);
}
printf("%d\n",ans);
return 0;
}