找出与状态转移有关的量,并且保证无后效性,
这道题可以找到移动区间的角度,简单有效的设计出状态,列出方程,
因为不可能去每个m(m<=5*10^4),找一个5,
所以我们在输入的时候,把数据处理成每个起始点的状态,
然后把每个状态设计成起始点,5个单位的区间,是否还有动物的状态,
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; inline int read() { int x=0;char c=getchar(); while(c<'0' || c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } int n,m,ans; const int N=10003,Mx=1<<5; int val[N][Mx],f[N][Mx]; int main() { n=read(),m=read(); int p,fail,like,F,L,xx; for(int i=1;i<=m;i++) { p=read(),fail=read(),like=read(); F=L=0; for(int j=1;j<=fail;j++) { xx=read(); F|=(1<<((p+4-xx)%n)); } for(int j=1;j<=like;j++) { xx=read(); L|=(1<<((p+4-xx)%n)); } for(int j=0;j<Mx;j++) if( (j&L) || ((~j)&F) ) val[p][j]++; } //先是第一个状态,然后往后面加0/1 for(int i=0;i<Mx;i++) { memset(f,128,sizeof(f)); f[0][i]=0; for(int j=1;j<=n;j++) for(int s=0;s<Mx;s++) f[j][s]=max(f[j-1][s>>1],f[j-1][(s>>1)+16]) +val[j][s]; ans=max(ans,f[n][i]); } printf("%d ",ans); return 0; }