luogu P5289 [十二省联考2019]皮配 背包
LINK:皮配
我承认是一道很难的题目。
不过对于这道题 部分分的提示显得尤为重要。
首先是 40分的暴力dp 很容易想 但是不容易写。
从40分可以发现我们只需要把蓝阵营和鸭派系的人数给存在起来就行了 此时可以获得50分。
观察题目中存在k==0的情况 可以发现 加入阵营和派系没有什么关系 所以就可以分开的做。
考虑100分 容易发现有毒的学校就30个 对于这三十个城市单独做暴力dp 剩下的按照上述方法。
一个难点:可以发现 学校选择的派系是影响城市的 所以感觉这样做不太行。
把有毒的城放在一起dp 很遗憾这样做复杂度最快也是\(nm^2\)的 过不了。
可以发现 对于那些没有毒的学校但有毒的城市来说 没有毒的学校还是可以对于派系随便选的。
对于有毒的城市选择阵营的时候一起做 选择派系的时候单独做。
这样还是只做了k个城市。
设总体的状态为f[i][j]表示前T个城市蓝阵营i人鸭派系j的方案数。
对于每个城市单独dp的话需要提前处理一个g数组 表示当前城市 前G个学校蓝阵营i人鸭派系j人的方案数。
进一步的可以发现这个状态可以变成g1[j]表示加入蓝阵营鸭派系j人 g2[j]表示加入红阵营j人的方案数。
可以发现合并的时候还要枚举一个决策k 所以总复杂度为\(km^3\)的。
一个trick 直接让g1和g2代替f数组 然后再进行转移 这样就不需要合并背包了。
复杂度\(km^2\). 没开o2速度排在rk8 常数海星. !注意边界问题。
const int MAXN=1010,maxn=2510;
int n,T,c,C0,C1,sum,D0,D1,lim1,lim2;
int sc[MAXN],wc[MAXN],f[maxn][maxn];
struct wy{int c,s;int op;}t[MAXN];
int f1[maxn],f2[maxn],g1[maxn][maxn],g2[maxn][maxn];
inline void add(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
inline int cmp(wy a,wy b){return a.c<b.c;}
inline int calc1(int s)
{
int l=max(0,sum-s-C1),r=C0-s;
if(l>r)return 0;
if(!l)return f1[r];
return (f1[r]-f1[l-1]+mod)%mod;
}
inline int calc2(int s)
{
int l=max(0,sum-s-D1),r=D0-s;
if(l>r)return 0;
if(!l)return f2[r];
return (f2[r]-f2[l-1]+mod)%mod;
}
inline void cle()
{
rep(1,n,i)sc[i]=wc[i]=0;
rep(0,max(C0,D0),i)f1[i]=f2[i]=0;
rep(0,lim1,i)rep(0,lim2,j)g1[i][j]=g2[i][j]=f[i][j]=0;
lim1=lim2=sum=0;
}
int main()
{
freopen("1.in","r",stdin);
get(T);
while(T--)
{
get(n);get(c);
get(C0);get(C1);get(D0);get(D1);
rep(1,n,i)
{
int get(x),get(y);
t[i]=(wy){x,y,0};
sum+=y;wc[x]+=y;
}
C0=min(C0,sum);C1=min(C1,sum);
D0=min(D0,sum);D1=min(D1,sum);
int get(Q);
rep(1,Q,i)
{
int get(x),get(y);
op(x)=y+1;sc[c(x)]=1;
}
f1[0]=f2[0]=1;
//f1对城市进行dp f2对学校进行dp.
rep(1,c,i)
{
if(sc[i]||!wc[i])continue;
fep(C0,wc[i],j)add(f1[j],f1[j-wc[i]]);
}
rep(1,n,i)
{
if(op(i))continue;
fep(D0,s(i),j)add(f2[j],f2[j-s(i)]);
}
//对所有有毒的城市进行dp.
//f[i][j]表示蓝阵营i人鸭派系j人的方案数.
int flag=1,sum1=0,sum2=0;//分别表示进入阵营和进入派系的人数.
sort(t+1,t+1+n,cmp);f[0][0]=1;
rep(1,c,G)
{
int st=flag;
while(c(flag)==G&&flag<=n)++flag;
int en=flag-1;
if(!sc[G])continue;
rep(0,lim1,i)rep(0,lim2,j)g2[i][j]=g1[i][j]=f[i][j];
rep(st,en,k)//只dp有毒的城市.
{
if(op(k))
{
sum2+=s(k);
lim2=min(sum2,D0);
fep(lim1,0,i)fep(lim2,0,j)
{
g1[i][j]=((j>=s(k)?g1[i][j-s(k)]*(op(k)!=1):0)+g1[i][j]*(op(k)!=2))%mod;
g2[i][j]=((j>=s(k)?g2[i][j-s(k)]*(op(k)!=3):0)+g2[i][j]*(op(k)!=4))%mod;
}
}
}
sum1+=wc[G];
lim1=min(sum1,C0);
fep(lim1,0,i)fep(lim2,0,j)f[i][j]=((i>=wc[G]?g1[i-wc[G]][j]:0)+g2[i][j])%mod;
}
rep(1,max(C0,D0),i)add(f1[i],f1[i-1]),add(f2[i],f2[i-1]);
int ans=0;
rep(0,lim1,i)
rep(0,lim2,j)
add(ans,(ll)f[i][j]*calc1(i)%mod*calc2(j)%mod);
put(ans);cle();
}
return 0;
}
luogu P5289 [十二省联考2019]皮配 背包的更多相关文章
- luogu P5289 [十二省联考2019]皮配
传送门 首先考虑一个正常的dp,设\(f_{i,j,k}\)为前\(i\)个学校,\(j\)人在\(\color{#0000FF}{蓝阵营}\),\(k\)人在\(\color{#654321}{吔} ...
- 洛谷P5289 [十二省联考2019]皮配(01背包)
啊啊啊边界判错了搞死我了QAQ 这题是一个想起来很休闲写起来很恶心的背包 对于\(k=0\)的情况,可以发现选阵营和选派系是独立的,对选城市选阵营和学校选派系分别跑一遍01背包就行了 对于\(k> ...
- 【BZOJ5498】[十二省联考2019]皮配(动态规划)
[BZOJ5498][十二省联考2019]皮配(动态规划) 题面 BZOJ 洛谷 题解 先考虑暴力\(dp\),设\(f[i][j][k]\)表示前\(i\)所学校,有\(j\)人在某个阵营,有\(k ...
- Luogu5289 十二省联考2019皮配(动态规划)
将选择导师看成先选阵营再选派系,这样有显然的O(nm2)暴力,即按城市排序后,设f[i][j][k]为前i个学校中第一个阵营有j人第一个派系有k人的方案数,暴力背包. 对于k=0,可以发现选阵营和选派 ...
- 【LuoguP5289】[十二省联考2019] 皮配
题目链接 题目描述 略 Sol 一道背包问题 首先暴力做法设 \(dp[i][j][k]\) 表示前 \(i\) 个城市的学校被分到第一阵营 \(j\) 人 第一门派 \(k\) 人的方案数. 中间一 ...
- Luogu P5285 [十二省联考2019]骗分过样例
Preface ZJOI一轮被麻将劝退的老年选手看到这题就两眼放光,省选也有乱搞题? 然后狂肝了3~4天终于打完了,期间还补了一堆姿势 由于我压缩技术比较菜,所以用的都是非打表算法,所以一共写了5K- ...
- luogu P5291 [十二省联考2019]希望
luogu loj 无论最终结果将人类历史导向何处 \(\quad\)我们选择 \(\quad\quad\)\(\large{希望}\) 诶我跟你讲,这题超修咸的 下面称离连通块内每个点距离不超过\( ...
- Luogu P5290 [十二省联考2019]春节十二响
这题是最近看到的今年省选题中最良心的一道了吧 看题+想题+写题都可以在0.5h内解决,送分含义明显啊 首先理解了题意后我们很快就能发现两个点如果要被分在一段那么必须在它们的祖先处合并 首先我们考虑下二 ...
- Luogu P5284 [十二省联考2019]字符串问题
好难写的字符串+数据结构问题,写+调了一下午的说 首先理解题意后我们对问题进行转化,对于每个字符串我们用一个点来代表它们,其中\(A\)类串的点权为它们的长度,\(B\)类串的权值为\(0\) 这样我 ...
随机推荐
- 洛谷 P4408 [NOI2003]逃学的小孩
题目传送门 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚, ...
- mysql根据逗号分割的字符串去关联查询另外一个表的数据
1.说明 在做显示数据的时候,一个字段会存那种逗号分割的字符串,那如何去根据逗号分割字符串去查询另一个表的数据呢? 首先我们查看一下需要显示的数据 select * from company wher ...
- 【js】栈方法和队列方法
栈方法:后进先出,推入(push)和弹出(pop):push("**")返回数组长度,pop()返回弹出的项. var colors = new Array(); // 创建一个数 ...
- 【DevCloud · 敏捷智库】两种你必须了解的常见敏捷估算方法
背景 在某开发团队辅导的回顾会议上,团队成员对于优化估计具体方法上达成了一致意见.询问是否有什么具体的估计方法来做估算. 问题分析 回顾意见上大家对本次Sprint的效果做回顾,其中80%的成员对于本 ...
- MYSQL 之 JDBC(二): 数据库连接(二)通过DriverManager获取数据库连接
通过DriverManager获取数据库连接 修改一下配置文件 driver=com.mysql.cj.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/ ...
- redis入门指南(三)—— 事务、过期时间、SORT命令、消息通知与管道
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 事务 1.redis中的事务由一组命令的集合组成,要么都执行,要么都不执行,同时redis的事务 ...
- 如何用HMS Nearby Service给自己的App添加近距离数据传输功能
当你给朋友发送手机资料时,过了很久进度条却动也不动:当你想发送大文件给同事时,仅一个文件就用光了你所有流量:当你跟朋友乘坐飞机时想一起玩游戏时,却因没有网络无奈放弃. 们生活中似乎经常能遇到这 ...
- Ethical Hacking - GAINING ACCESS(23)
CLIENT SIDE ATTACK - BeEF Framework Hooking targets using MITMF Tools: MITMF and BeEF Start BeEF and ...
- GPO - Windows Server Update Services
Windows Server Update Services Configuration Wizard: Approve procedure of these updates is very tiri ...
- 搭建sonarqube分析golang代码
准备postgres 为什么不使用Mysql呢,因为从7.9就不支持了 docker启动postgres docker run -d \ --name sonar-postgres \ -e POST ...