bzoj 5498: [2019省队联测]皮配【dp】
是个神仙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】的更多相关文章
- BZOJ 5495: [2019省队联测]异或粽子 (trie树)
这题果然是原题[BZOJ 3689 异或之].看了BZOJ原题题解,发现自己sb了,直接每个位置维护一个值保存找到了以这个位置为右端点的第几大,初始全部都是1,把每个位置作为右端点能够异或出来的最大值 ...
- bzoj 5499: [2019省队联测]春节十二响【堆】
首先看两条链怎么合并,贪心可得是从大到小取max,多条链同理 所以dfs合并子树的大根堆即可,注意为了保证复杂度,合并的时候要合并到最长链上,证明见长链剖分 #include<iostream& ...
- bzoj 5496: [2019省队联测]字符串问题【SAM+拓扑】
有一个想法就是暴力建图,把每个A向有和他相连的B前缀的A,然后拓扑一下,这样的图是n^2的: 考虑优化建图,因为大部分数据结构都是处理后缀的,所以把串反过来,题目中要求的前缀B就变成了后缀B 建立SA ...
- bzoj 5495: [2019省队联测]异或粽子【可持久化trie+大根堆】
和bzoj4504差不多,就是换了个数据结构 像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么 ...
- BZOJ 5495: [2019省队联测]异或粽子 可持久化trie+堆
和超级钢琴,异或之三倍经验 $?$ 堆+贪心素质三连 $?$ 好无聊...... code: #include <bits/stdc++.h> #define N 500006 #defi ...
- BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)
题意 略 分析 考场上写了暴力建图40分溜了-(结果只得了30分) 然后只要优化建边就行了 首先给出的支配关系无法优化,就直接A向它支配的B连边. 考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两 ...
- BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)
题意 略 分析 稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有 ...
- 【BZOJ5499】[2019省队联测]春节十二响(贪心)
[BZOJ5499][2019省队联测]春节十二响(贪心) 题面 BZOJ 洛谷 题解 如果是一条折链,显然维护两侧的值,每次两个堆分别弹出一个\(max\)然后合并一下,最后再放回去就可以了. 那么 ...
- bzoj 5251: [2018多省省队联测]劈配
Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ...
随机推荐
- CMS - tabBar
Tips:如果网页图片(文字)看不清,请按CTRL+鼠标滚轮 1.建议使用阿里图库 或者 easyicon 2.建议使用81*81且低于40KB的图片(建议jpg) 3.如需查看脑图结构,请点击:ta ...
- 利用ctypes调用Fortran程序
本来python下面调用fortran最傻瓜方便的办法就是f2py,但是若fortran和C混合编程的代码,分别指定gfortran和gcc为编译器,在windows下面f2py直接报错 那么ctyp ...
- 自己定义msi安装包的运行过程
有时候我们须要在程序中运行还有一个程序的安装.这就须要我们去自己定义msi安装包的运行过程. 比方我要做一个安装管理程序,能够依据用户的选择安装不同的子产品.当用户选择了三个产品时,假设分别显示这三个 ...
- 关闭mongodb 集群
[root@hadoop1 ~]# ps -aux | grep mongodb; root ? Sl : : /usr/local/mongodb/bin/mongod -f /usr/local/ ...
- 获取Android设备无线和以太网MAC地址
package com.raycloud.wolf.blogformac; import android.net.wifi.WifiManager; import android.support.v7 ...
- 推断php操作mysql(添删改查)是否成功
近期在使用CI框架 , 可是里面的数据库操作没有ThinkPhp方便 , 不知道数据库操作的反馈信息 , 仅仅好借助原生方法来推断是否操作数据库成功 推断php操作mysql(添删改查)是否成功,主要 ...
- bzoj4664: Count
是bzoj4498: 魔法的碰撞的哥哥题,我只写了一种 不一样的地方在于贡献有负数,第三维要保存的不能仅仅是0~L,这样空间会炸裂 考虑如何把贡献变成正的 假如要求最优解,那么一定是按顺序排,混乱度为 ...
- 软件安全测试新武器 ——浅谈基于Dynamic Taint Propagation的测试技术
软件安全测试是保证软件能够安全使用的最主要的手段,如何进行高效的安全测试成为业界关注的话题.多年的安全测试经验告诉我们,做好软件安全测试的必要条件是:一是充分了解软件安全漏洞,二是拥有高效的软件安全测 ...
- JavaScript函数调用规则
1. [代码][JavaScript]代码 JavaScript函数调用规则一 (1)全局函数调用:function makeArray( arg1, arg2 ){ return [t ...
- html5--6-7 CSS选择器4
html5--6-7 CSS选择器4 实例 学习要点 掌握常用的CSS选择器 了解不太常用的CSS选择器 什么是选择器 当我们定义一条样式时候,这条样式会作用于网页当中的某些元素,所谓选择器就是样式作 ...