题目: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;
}

相关文章: