题目:https://www.luogu.org/problemnew/show/P5289
考场上只写了 50 分的 DP 。并且没意识到只记录两个导师的人数就行了,所以记了 3 个。不过写的记搜,还是得了 50 分。
#include<cstdio> #include<cstring> #include<algorithm> #include<map> #define ll long long using namespace std; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar(); return fx?ret:-ret; } const int N=1005,mod=998244353; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int n,c,c0,c1,d0,d1,ct[N]; struct Node{ int bh,s,p; bool operator< (const Node &b)const {return bh<b.bh;} }a[N]; struct Dt{ int cr,s0,s1,s2;bool fx; Dt(int c=0,bool f=0,int s0=0,int s1=0,int s2=0): cr(c),fx(f),s0(s0),s1(s1),s2(s2) {} bool operator< (const Dt &b)const { if(cr!=b.cr)return cr<b.cr; if(fx!=b.fx)return fx<b.fx; if(s0!=b.s0)return s0<b.s0; if(s1!=b.s1)return s1<b.s1; return s2<b.s2; } }; map<Dt,int> mp; int dfs(int cr,bool fx,int s0,int s1,int s2,int s3) { if(cr>n)return 1; Dt tp=Dt(cr,fx,s0,s1,s2); if(mp.count(tp))return mp[tp]; int ret=0, p=a[cr].p, s=a[cr].s; if(a[cr-1].bh==a[cr].bh) { if(!fx) { if(s2+s<=d0&&p!=1) ret=upt(ret+dfs(cr+1,fx,s0+s,s1,s2+s,s3)); if(s3+s<=d1&&p!=2) ret=upt(ret+dfs(cr+1,fx,s0+s,s1,s2,s3+s)); } else { if(s2+s<=d0&&p!=3) ret=upt(ret+dfs(cr+1,fx,s0,s1+s,s2+s,s3)); if(s3+s<=d1&&p!=4) ret=upt(ret+dfs(cr+1,fx,s0,s1+s,s2,s3+s)); } } else { if(s0+ct[a[cr].bh]<=c0) { if(s2+s<=d0&&p!=1) ret=upt(ret+dfs(cr+1,0,s0+s,s1,s2+s,s3)); if(s3+s<=d1&&p!=2) ret=upt(ret+dfs(cr+1,0,s0+s,s1,s2,s3+s)); } if(s1+ct[a[cr].bh]<=c1) { if(s2+s<=d0&&p!=3) ret=upt(ret+dfs(cr+1,1,s0,s1+s,s2+s,s3)); if(s3+s<=d1&&p!=4) ret=upt(ret+dfs(cr+1,1,s0,s1+s,s2,s3+s)); } } mp[tp]=ret; return ret; } int main() { freopen("mentor.in","r",stdin); freopen("mentor.out","w",stdout); int T=rdn(); while(T--) { n=rdn();c=rdn();c0=rdn();c1=rdn();d0=rdn();d1=rdn(); mp.clear(); for(int i=1;i<=n;i++)a[i].p=0; for(int i=1;i<=c;i++)ct[i]=0; int sm=0; for(int i=1;i<=n;i++) { a[i].bh=rdn(); a[i].s=rdn(); ct[a[i].bh]+=a[i].s; sm+=a[i].s; } if(sm>min(c0+c1,d0+d1)){puts("0");continue;} int k=rdn(); for(int i=1,d;i<=k;i++) d=rdn(), a[d].p=rdn()+1; sort(a+1,a+n+1); printf("%d\n",dfs(1,0,0,0,0,0)); } return 0; }