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\) 这样我 ...
随机推荐
- python 实现汉诺塔
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘. 大梵天命令婆罗门把圆盘从下面开始按大小顺 ...
- 【树形DP】洛谷P2585 [ZJOI2006] 三色二叉树
[树形DP]三色二叉树 标签(空格分隔): 树形DP [题目] 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1 ...
- Linux系统 Centos7 环境基于Docker部署Rocketmq服务
消息队列 基本概述 MQ,Message Queue,基于TCP协议构建的简单协议,区别于具体的通信协议. 基于通信协议定义和抽象的更高层次的通信模型,一般都是生产者和消费者模型,又或者说服务端和客户 ...
- kubernetes系列(十二) - 存储之Secret
1. Secret简介 2. Secret类型 3. Service Account 4. Opaque 4.1 Opaque类型说明 4.2 Opaque创建方式 4.2.1 命令行创建 4.2.2 ...
- es6 模块与commonJS的区别
在刚接触模块化开发的阶段,我总是容易将export.import.require等语法给弄混,今天索性记个笔记,将ES6 模块知识点理清楚 未接触ES6 模块时,模块开发方案常见的有CommonJS. ...
- 数据可视化之powerBI入门(十二)PowerBI中最重要的函数:CALCULATE
https://zhuanlan.zhihu.com/p/64382849 介绍DAX的时候,特别强调过一个重要的函数:CALCULATE,本文就来揭秘这个函数的计算原理以及它是如何影响上下文的. C ...
- 数据可视化之PowerQuery篇(十九)PowerBI数据分析实践第三弹 | 趋势分析法
https://zhuanlan.zhihu.com/p/133484654 本文为星球嘉宾"海艳"的PowerBI数据分析工作实践系列分享之三,她深入浅出的介绍了PowerBI ...
- electron代码审计
解包 Electron跨平台程序破解https://www.52pojie.cn/thread-563895-1-1.html Electron封装的跨平台程序破解的一般思路: 安装npm(至于如何安 ...
- spring boot实现简单的登录拦截
一.思路 1.在pom.xml导入相关包 2.先写个简单的认证适配器(WebSecurityConfig extends WebSecurityConfigurerAdapter),登录拦截后就会跳转 ...
- (3)html-webpack-plugin的作用
在内存中生成index.html页面 在前面的内容中我们已经知道了如何在内存中打包main.js并引入到页面中. 同样的,我们也可以把index.html也打包放入到内存中. 安装html-webpa ...