【CSP2019】洛谷5664 Emiya家的饭题解(容斥+DP)

Tarjan割点 [定义]: 在无向连通图中,如果将其中一个点以及所有连接该点的边去掉,图就不再连通,那么这个点就叫做割点。 在无向连通图中,如果将其中一条边去掉,图就不再连通,那么这条边叫桥。 [思想]: 割点:1)当前节点u为树根的时候,这个节点要有至少两棵子树,否则去掉该节点不会有影响。 2)当前节点u不是树根的时候,要满足low[v]>=dfn[u],注意u是v的父亲 ... 阅读详情

题目:luogu5664.
题目大意:给定一个 n n n行 m m m列的矩阵 a i , j a_{i,j} ai,j​,选出一些位置满足:
1.至少选出一个位置.
2.每行只选一个数.
3.每一列选的位置数不能超过选的总位置数的一半.
求所有方案选出的数的乘积的和,不算一个都不选的方案.
1 ≤ n ≤ 100 , 1 ≤ m ≤ 2000 1\leq n\leq 100,1\leq m\leq 2000 1≤n≤100,1≤m≤2000,答案对 998244353 998244353 998244353取模.

首先直接计算并不容易,所以考虑用满足 1 , 2 1,2 1,2的所有方案减去满足 1 , 2 1,2 1,2但不满足 3 3 3的方案.

满足 1 , 2 1,2 1,2的总方案很好求,我们可以直接用一个线性DP解决这个问题.即设 f [ i ] f[i] f[i]表示前 i i i行的总方案,那么有:
f [ i ] = ( 1 + ∑ j = 1 m a i , j ) f [ i − 1 ] f[i]=\left(1+\sum_{j=1}^{m}a_{i,j}\right)f[i-1] f[i]=(1+j=1∑m​ai,j​)f[i−1]

考虑对于每个不满足 3 3 3的方案,如果某一列选出的位置数超过一半,则不可能有其它列超过一半,所以暴力枚举是哪一列超过了一半.

接下来,假设超过一半的是第 p p p列,很容易想到一个DP状态,设 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示前 i i i行,其中第 p p p列选了 j j j行,不是第 p p p列选了 k k k行,那么有:
f [ i ] [ j ] [ k ] = f [ i − 1 ] [ j ] [ k ] + a i , p f [ i − 1 ] [ j − 1 ] [ k ] + ( ∑ t = 1 m a i , t − a i , p ) f [ i − 1 ] [ j ] [ k − 1 ] f[i][j][k]=f[i-1][j][k]+a_{i,p}f[i-1][j-1][k]+\left(\sum_{t=1}^{m}a_{i,t}-a_{i,p}\right)f[i-1][j][k-1] f[i][j][k]=f[i−1][j][k]+ai,p​f[i−1][j−1][k]+(t=1∑m​ai,t​−ai,p​)f[i−1][j][k−1]

时间复杂度 O ( m n 3 ) O(mn^{3}) O(mn3),可以获得84pts.

考虑如何优化这个DP过程,容易发现我们并不需要关心第 p p p列和不是第 p p p列选的具体数量,只要知道它们的大小关系即可,所以设 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i行,其中第 p p p列比其他列多选了 j j j行的方案数,那么有:
f [ i ] [ j ] = f [ i − 1 ] [ j ] + a i , p f [ i − 1 ] [ j − 1 ] + ( ∑ t = 1 m a i , t − a i , p ) f [ i − 1 ] [ j + 1 ] f[i][j]=f[i-1][j]+a_{i,p}f[i-1][j-1]+\left(\sum_{t=1}^{m}a_{i,t}-a_{i,p}\right)f[i-1][j+1] f[i][j]=f[i−1][j]+ai,p​f[i−1][j−1]+(t=1∑m​ai,t​−ai,p​)f[i−1][j+1]

时间复杂度 O ( m n 2 ) O(mn^{2}) O(mn2),可以获得100pts.

代码如下(需要开O2):

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N=100,M=2000,mod=998244353;

int add(int a,int b,int p=mod){return a+b>=p?a+b-p:a+b;}
int sub(int a,int b,int p=mod){return a-b<0?a-b+p:a-b;}
int mul(int a,int b,int p=mod){return (LL)a*b%p;}
void sadd(int &a,int b,int p=mod){a=add(a,b,p);}
void ssub(int &a,int b,int p=mod){a=sub(a,b,p);}
void smul(int &a,int b,int p=mod){a=mul(a,b,p);} 

int n,m,a[N+9][M+9];

void into(){
  scanf("%d%d",&n,&m);
  for (int i=1;i<=n;++i)
    for (int j=1;j<=m;++j){
      scanf("%d",&a[i][j]);
      sadd(a[i][0],a[i][j]);
	}
}

int ans;

void Get_ans(){
  ans=1;
  for (int i=1;i<=n;++i) sadd(ans,mul(ans,a[i][0]));
  ssub(ans,1);
}

int dp[2][N*2+9],old,now;

void Get_dp(int p){
  old=1;now=0;
  for (int i=0;i<=n<<1;++i) dp[now][i]=0;
  dp[now][n]=1;
  for (int i=1;i<=n;++i){
  	old^=1;now^=1;
  	for (int j=0;j<=n<<1;++j){
  	  dp[now][j]=dp[old][j];
  	  if (j>0) sadd(dp[now][j],mul(a[i][p],dp[old][j-1]));
  	  if (j<n<<1) sadd(dp[now][j],mul(sub(a[i][0],a[i][p]),dp[old][j+1]));
  	}
  }
  for (int i=n+1;i<=n<<1;++i) ssub(ans,dp[now][i]);
}

void work(){
  Get_ans();
  for (int i=1;i<=m;++i) Get_dp(i);
}

void outo(){
  printf("%d\n",ans);
}

int main(){
  into();
  work();
  outo();
  return 0;
}
C++的算法:割点与割边 阅读详情

相关推荐

OpenWrt kmod内核不兼容?手把手教你用脚本强制安装驱动模块(附国内镜像源)

本文详细解决了OpenWrt kmod内核不兼容问题,提供智能脚本强制安装驱动模块的方法,并附有国内镜像源加速配置。通过自动化脚本修改内核MD5校验值,确保kmod包正常安装,同时推荐多个国内镜像源以提升下载速度。

weixin_42549451的博客 539

洛谷 P5664 Emiya 家今天的饭 题解

纯暴力(32 pts) 开始的第一思路,可以过测试点1-8 直接枚举出每种烹饪方法所用的主要食材 用搜索枚举,传入两个参数:现在枚举的烹饪方法编号以及在此之前的方案数 代码: #include <iostream> #include <cstdio> const long long mod = 998244353 ; using namespace std ;...

xsaploser的博客 520

三相逆变器拓扑结构的分析及应用场景

三相逆变器是电力电子领域中广泛应用的一种设备,用于将直流电转换为交流电。不同的拓扑结构在性能、成本、复杂度和应用领域上存在差异。小编将在本文中将进一步拓展对三相逆变器拓扑结构的分析,并探讨其适用的应用场景。

道合顺的博客 2235

【CSP-S 2019】【洛谷P5664】Emiya 家今天的饭【dp】

菜到爆炸qwq,84pts的出血大放送都没拿到

stoorz 994

Silvaco 学习笔记——物理模型:载流子产生复合模型

对载流子的复合机制进行总结

reactortiger的博客 1万+

K230+canMV开发中常见的数据类型转换参考示例

【代码】K230+canMV开发中常见的数据类型转换参考示例。

weixin_47446386的博客 67

SSLOJ 1437.逮虾户【二分答案】

就这样吧

qq_35786326的博客 249

ubuntu下安装多版本cuda及版本切换教程

首先,从官网下载所需版本的cuda安装包,下载链接。选择对应版本后,会跳转到该版本的配置信息页面。比如我是ubuntu20.04系统,已经安装好了cuda10.0,但是现在还需要用到cuda9.0。那么,在选定版本后,配置信息如下图所示(由于Version选项中没有20.04,因此我们随便选一个即可,这里选的16.04,这一选项不会影响后面的安装),Installer Type选择为runfile(因为使用deb文件进行安装的话,可能会将已经安装的较新的显卡驱动给替换掉),选择好之后点击Base Insta

zeeq的博客 3万+

Luogu – P5664 – [CSP-S2019]Emiya家今天的饭

更好的阅读体验:TonyYin - Blog 题目地址:P5664 Emiya 家今天的饭 - 洛谷 | 计算机科学教育新生态 题意 一共 nnn 种烹饪方法和 mmm 种主要食材,每道菜对应一种方法和一种食材。使用第 iii 种方法和 第 jjj 种食材,可以做出 ai,ja_{i, j}ai,j​ 道不同的菜。求有多少个集合满足如下条件: 非空 每道菜烹饪方法互不相同 集合中每种主要食材的菜数不超过集合大小的一半 数据范围:n≤100,m≤2000n\leq 100, m\leq 2000n≤100

TonyYin's Blog 263

某音私信接口二进制解析

本文探讨了某音私信接口的二进制请求处理过程,重点分析了请求体中的非文本字符和混合编码结构。文章详细描述了编码过程,包括使用Protocol Buffers的序列化方法将结构化数据转换为字节流,并通过Uint8Array包装成二进制数组。作者展示了如何提取和补全s.encode方法,并将其转化为Base64字符串以便在Python中解码执行

码王吴彦祖的博客 900

OsgEarth —— 笔记1 - 创建地球的earth文件

效果         正文      1、准备一张全球的渲染图(tif格式)、一张全球的高程图(tif格式)        2、创建并编写.earth文件           在步骤1目录下创建china-simple.earth,并将如下内容写入。 <map name="Globe" type="geocentric" version="2"> <!-- 全球影像图 --> <image name="GlobeImage" driver="gdal"> &l

7681

P5664 [CSP-S2019] Emiya 家今天的饭

P5664 [CSP-S2019] Emiya 家今天的饭

GDW07的博客 2万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

算法随笔:图论问题之割点割边

关于图论中无向图连通性问题里的割点、割边

qq_45554473的博客 3061

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

割点、割边、双连通分支

一、割点、割边、双连通分支概念 挂接点(Articulation point)就是割点(Cut Vertex) 桥(Bridge)就是割边(Cut Edge) 割点:v为割点,则去掉v后,图的连通分支增加。 割边:v为割边,则去掉v后,图的连通分支增加。 割点形式化的定义:a是割点当且仅当存在两个点u,v使得u到v的每条路径都会经过a。(去掉a后,u到v没有路径) 边双

xiazdong 5636

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

知识点 - 割点与割边

知识点 - 割点与割边 概念(一)割点 针对无向连通图,若删除一个点后使得该图不连通,则该点是割点。 注意:一个图中可能有多个割点 复杂度: O(N+M)O(N+M)O(N+M) 实现 我们在遍历所有点时会遇到割点(废话),主要是如何认定一个点是割点。假设访问到了k点,如果在没有访问过的点中,至少有一个点在不经过k点的情况下,无法回到已访问过的点,则k点是割点。(因为该图删除点k后不连通了) 算法...

qq_41848675的博客 1741

割点和割边

定义 割点的定义(均在无向图中):在一个连通图中,如果有一个顶点集合,删除这个集合中的点以及相关的边之后,连通块的数量会增多.我们就称这个顶点集合为割点集合.如果这个点集合中只有一个点,那么这个点就叫做割点. 割边的定义(均在无向图中):在一个连通图中,如果删去其中一条边后,连通块的数量会增多,那么我们称这条边为桥或者是割边. 例如这个图:A和B都是割点,其中A-B为桥或割边 ...

TL的博客 1万+

20 求图的割点和割边—Tarjan算法

求图的割点和割边—Tarjan算法

xuqw11111的专栏 3382

Tarjan算法超详细讲解(割点割边强连通)

本文出自我的掘金博客, 欢迎大家访问传送门 今天我主要介绍Tarjan算法在割点割边以及强连通分量中的应用以及缩点技巧 按照老规矩, 先上两道模板题 【模板】强连通分量 【模板】割点(割顶) 割点割边 一, 离散数学中的定义: 割点: 无向连通图中,去掉一个顶点及和它相邻的所有边,图中的连通分量数增加,则该顶点称为割点。 割边: 无向联通图中,去掉一条边,图中的连通分量数增加,则这条边,称为...

汪阿少的博客 8030

简单算法-割点和割边

一、什么是割点和割边? 1、割点:当在一个连通的图中,去除某个点,使得该图不再连通,而被去除的点就是该图的割点。 2、割边(桥):如割点一样,在一个连通的图中,去除某条边,使得该图不再连通,而被去除的条边就是该图的割边,也称桥。 二、如何判断是否为割点和割边? 首先, ...

weixin_57544905的博客 6917

L2-013红色警报(dijkstra最短路)

原题链接 战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。 输入格式: 输入在第一行给出两个整数N(0 < N ≤ 500)和M(≤ 5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数。随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔。在城市信息之后给出被攻占的

m0_46656833的博客 390

CF639F Bear and Chemistry(虚树,边双)

CF639F Bear and Chemistry Solution 显然题目的条件就是所有点在一个边双连通分量内。 所以我们先缩边双求出边双树。 然后对于每一个询问,对询问的点和边的端点建虚树,然后把询问的边连上跑tarjantarjantarjan求边双判断是否所有询问点在同一个边双内即可。 时间复杂度O((n+m)lgn)O((n+m)lgn)O((n+m)lgn)。 Code #include <vector> #include <list> #include <map

xmr_pursue_dreams的博客 523

Emiya 家今天的饭

一、题目 点此看题 二、解法 0x01 暴力 可以考虑搜索,时间复杂度O(mn)O(m^n)O(mn),可以拿到323232分的高分。 考虑m≤3m\leq 3m≤3的部分分,直接四维dpdpdp,定义dp[i][j][k][l]dp[i][j][k][l]dp[i][j][k][l]为前iii行分别选j,k,lj,k,lj,k,l个,转移也不难,时间复杂度O(n4m)O(n^4m)O(n4m),...

C202044zxy的博客 768

P5664 [CSP-S2019] Emiya 家今天的饭(dp+容斥)

[题目传送门]

m0_51841071的博客 523

luoguP5664 Emiya 家今天的饭

考虑维护一个差值 每次枚举是那个食材爆炸。。。然后就ok了 嘛,建议看题解这个题。。。 #include<bits/stdc++.h> using namespace std; long long n,m,mod = 998244353; long long a[105][2005],s[105],f[205][205],sum; void init(){ memset(f,0,...

到处遛鸟刑警 196

[CSP-S2019] Emiya 家今天的饭

Day 6+7 DP(那一年的day2题1,完全被支配了┭┮﹏┭┮)代码如下(示例):

qq_43649491的博客 218
上一篇: AtCoder Regular Contest 083 E Bichrome Tree 题解(树形DP)
下一篇: BZOJ3132 上帝造题的七分钟题解(树状数组+差分)
hezlik
博客等级 码龄9年 111粉丝 241原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值