是个神仙dp……

参考:https://www.luogu.org/blog/xzz-233/solution-p5289

设f[i][j][k]是前i个有限制的城市,所有学校中选蓝色阵营有j人,有限制的学校中鸭派系有k人的方案数;g[i][j]是前i个没有限制的城市,蓝色阵营有j人的方案数;h[i][j]是前i个没有限制的学校,鸭派系有j人的方案数

f的转移枚举当前阵营

全dp出来之后,把gh前缀和处理,然后一段一段的和f合并加到ans上

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2505,mod=998244353;
int T,n,c,c0,c1,d0,d1,k,m,ss,ans,b[N],s[N],f[N][N],f1[N][N],f2[N][N],g[N],h[N],ki[N],kp[N],v[N],ct[N],sum[N],sm[N];
vector<int>sc[N];
void jia(int &x,int y)
{
if((x+=y)>=mod)
x-=mod;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int main()
{
T=read();
while(T--)
{
memset(f,0,sizeof(f));
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
memset(g,0,sizeof(g));
memset(h,0,sizeof(h));
memset(sm,0,sizeof(sm));
memset(sum,0,sizeof(sum));
memset(ct,0,sizeof(ct));
for(int i=0;i<N;i++)
sc[i].clear();
ss=0,ans=0;
n=read(),c=read(),c0=read(),c1=read(),d0=read(),d1=read();
for(int i=1;i<=n;i++)
b[i]=read(),s[i]=read(),sum[b[i]]+=s[i],ss+=s[i];
m=k=read();
for(int i=1;i<=n;i++)
v[i]=-1;
for(int i=1;i<=k;i++)
{
ki[i]=read(),kp[i]=read();
ct[i]=b[ki[i]];
sc[b[ki[i]]].push_back(ki[i]);
v[ki[i]]=kp[i];
}
sort(ct+1,ct+1+m);
m=unique(ct+1,ct+1+m)-ct-1;
for(int i=1;i<=n;i++)
if(v[i]!=-1)
sm[b[i]]+=s[i];
f[0][0]=1;
for(int i=1,s1=0,s2=0;i<=m;i++)
{
s1=min(c0,s1+sum[ct[i]]),s2=min(d0,s2+sm[ct[i]]);
for(int o=0;o<=1;o++)
{
for(int j=0;j<=s1;j++)
for(int k=0;k<=s2;k++)
f1[j][k]=f[j][k];
for(int l=0,len=sc[ct[i]].size();l<len;l++)
{
int x=sc[ct[i]][l];
for(int j=s1;j>=0;j--)
for(int k=s2;k>=0;k--)
{
if(o==0)
{
f1[j][k]=0;
if(v[x]!=1&&j>=s[x])
jia(f1[j][k],f1[j-s[x]][k]);
if(v[x]!=0&&j>=s[x]&&k>=s[x])
jia(f1[j][k],f1[j-s[x]][k-s[x]]);
}
else
{
if(v[x]==3)
f1[j][k]=0;
if(v[x]!=2&&k>=s[x])
jia(f1[j][k],f1[j][k-s[x]]);
}
}
}
if(o==0)
{
int nw=sum[ct[i]]-sm[ct[i]];
for(int j=s1;j>=0;j--)
for(int k=s2;k>=0;k--)
{
if(j>=nw)
f1[j][k]=f1[j-nw][k];
else
f1[j][k]=0;
}
for(int j=0;j<=s1;j++)
for(int k=0;k<=s2;k++)
f2[j][k]=f1[j][k];
}
else
{
for(int j=0;j<=s1;j++)
for(int k=0;k<=s2;k++)
f[j][k]=(f1[j][k]+f2[j][k])%mod;
}
}
}
g[0]=1;
for(int i=1,smm=0;i<=c;i++)
if(sc[i].empty()&&sum[i])
{
smm=min(c0,smm+sum[i]);
for(int j=smm;j>=0;j--)
if(j>=sum[i])
jia(g[j],g[j-sum[i]]);
}
h[0]=1;
for(int i=1,smm=0;i<=n;i++)
if(v[i]==-1)
{
smm=min(d0,smm+s[i]);
for(int j=smm;j>=0;j--)
if(j>=s[i])
jia(h[j],h[j-s[i]]);
}
for(int i=1;i<=c0;i++)
jia(g[i],g[i-1]);
for(int i=1;i<=d0;i++)
jia(h[i],h[i-1]);
for(int i=0;i<=c0;i++)
if(ss-i-c1-1<c0-i)
for(int j=0;j<=d0;j++)
if(ss-j-d1-1<d0-j)
jia(ans,1ll*f[i][j]*(g[c0-i]-(ss-i-c1-1>=0?g[ss-i-c1-1]:0)+mod)%mod*(h[d0-j]-(ss-j-d1-1>=0?h[ss-j-d1-1]:0)+mod)%mod);
printf("%d\n",(ans+mod)%mod);
}
return 0;
}

bzoj 5498: [2019省队联测]皮配【dp】的更多相关文章

  1. BZOJ 5495: [2019省队联测]异或粽子 (trie树)

    这题果然是原题[BZOJ 3689 异或之].看了BZOJ原题题解,发现自己sb了,直接每个位置维护一个值保存找到了以这个位置为右端点的第几大,初始全部都是1,把每个位置作为右端点能够异或出来的最大值 ...

  2. bzoj 5499: [2019省队联测]春节十二响【堆】

    首先看两条链怎么合并,贪心可得是从大到小取max,多条链同理 所以dfs合并子树的大根堆即可,注意为了保证复杂度,合并的时候要合并到最长链上,证明见长链剖分 #include<iostream& ...

  3. bzoj 5496: [2019省队联测]字符串问题【SAM+拓扑】

    有一个想法就是暴力建图,把每个A向有和他相连的B前缀的A,然后拓扑一下,这样的图是n^2的: 考虑优化建图,因为大部分数据结构都是处理后缀的,所以把串反过来,题目中要求的前缀B就变成了后缀B 建立SA ...

  4. bzoj 5495: [2019省队联测]异或粽子【可持久化trie+大根堆】

    和bzoj4504差不多,就是换了个数据结构 像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么 ...

  5. BZOJ 5495: [2019省队联测]异或粽子 可持久化trie+堆

    和超级钢琴,异或之三倍经验 $?$ 堆+贪心素质三连 $?$ 好无聊...... code: #include <bits/stdc++.h> #define N 500006 #defi ...

  6. BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)

    题意 略 分析 考场上写了暴力建图40分溜了-(结果只得了30分) 然后只要优化建边就行了 首先给出的支配关系无法优化,就直接A向它支配的B连边. 考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两 ...

  7. BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)

    题意 略 分析 稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有 ...

  8. 【BZOJ5499】[2019省队联测]春节十二响(贪心)

    [BZOJ5499][2019省队联测]春节十二响(贪心) 题面 BZOJ 洛谷 题解 如果是一条折链,显然维护两侧的值,每次两个堆分别弹出一个\(max\)然后合并一下,最后再放回去就可以了. 那么 ...

  9. bzoj 5251: [2018多省省队联测]劈配

    Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ...

随机推荐

  1. h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片

    得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...

  2. ADO.NET EF 4.2 中的查询缓存(避免查询缓存)

    在WinForm系统中遇到了个问题,Form1是查询窗口,根据条件查询出所有数据,双击列表后创建弹出Form2窗口编辑单个记录,但编辑后保存后,在Form2中查询到的还是旧的数据,实际数据库中已经更新 ...

  3. 阿里云 ubuntu 14.04 模板上安装 docker

    ubuntu 14.04 的内核是 3.13 ,所以内核不用升级. 安装过程例如以下: # apt-get update # apt-get install apt-transport-https # ...

  4. Django-权限信息初始化

    数据库 from django.db import models class Menu(models.Model): """ 菜单组: """ ...

  5. Appium,IOS 模拟器,Java工程搭建

    首先进入sample code Test App 有TestApp.xcodeproj文件的工程目录下 下编译出TestApp.app文件 1.新建 java 工程 2.import需要的包 新建cl ...

  6. 从数据源拉取数据,将数据内容与一组搜索项做比对 go func() chanel

    https://github.com/goinaction/code [root@hadoop3 sample]# go run main.go 2018/07/30 17:45:39 Registe ...

  7. These interactions can be expressed as complicated, large scale graphs. Mining data requires a distributed data processing engine

    https://databricks.com/blog/2014/08/14/mining-graph-data-with-spark-at-alibaba-taobao.html

  8. CSS3 的10种Loading

    昨晚用CSS3实现了几种常见的Loading效果,虽然很简单,但还是分享一下,顺便也当是做做笔记…… 第1种效果: 代码如下: <div class="loading"> ...

  9. 【转】【录教程必备】推荐几款屏幕录制工具(可录制GIF)

    我们经常会遇到一些场景,需要你向别人展示一些操作或是效果——例如告诉别人某某软件的配置步骤啊.刚设计出来网站的动画效果怎么样啊.某某电影里面的一个镜头多么经典啊.打得大快人心的NBA绝杀瞬间是怎么回事 ...

  10. 修改u-boot的开机logo及显示过程【转】

    本文转载自;http://blog.csdn.net/voice_shen/article/details/6789424 [ u-boot: Git://git.denx.de/u-boot.git ...