题目

题目链接:https://www.luogu.org/problem/P5664

Emiya 是个擅长做菜的高中生,他共掌握 \(n\) 种烹饪方法,且会使用 \(m\) 种主要食材做菜。为了方便叙述,我们对烹饪方法从 \(1 \sim n\) 编号,对主要食材从 \(1 \sim m\) 编号。

Emiya 做的每道菜都将使用恰好一种烹饪方法与恰好一种主要食材。更具体地,Emiya 会做 \(a_{i,j}\) 道不同的使用烹饪方法 \(i\) 和主要食材 \(j\) 的菜(\(1 \leq i \leq n, 1 \leq j \leq m\)),这也意味着 Emiya 总共会做 \(\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} a_{i,j}\) 道不同的菜。

Emiya 今天要准备一桌饭招待 Yazid 和 Rin 这对好朋友,然而三个人对菜的搭配有不同的要求,更具体地,对于一种包含 \(k\) 道菜的搭配方案而言:

  • Emiya 不会让大家饿肚子,所以将做至少一道菜,即 \(k \geq 1\)
  • Rin 希望品尝不同烹饪方法做出的菜,因此她要求每道菜的烹饪方法互不相同
  • Yazid 不希望品尝太多同一食材做出的菜,因此他要求每种主要食材至多在一半的菜(即 \(\lfloor \frac{k}{2} \rfloor\) 道菜)中被使用

这里的 \(\lfloor x \rfloor\) 为下取整函数,表示不超过 \(x\) 的最大整数。

这些要求难不倒 Emiya,但他想知道共有多少种不同的符合要求的搭配方案。两种方案不同,当且仅当存在至少一道菜在一种方案中出现,而不在另一种方案中出现。

Emiya 找到了你,请你帮他计算,你只需要告诉他符合所有要求的搭配方案数对质数 \(998,244,353\) 取模的结果。

思路:

我菜死了。

其实这道题可以转换为一个\(n\times m\)的矩阵,矩阵每一行最多只能选一个数,每一列可以选若干个数,询问有多少种方案满足选取的每一列的个数均不超过选取总个数的一半。

正难则反。我们发现,对于不合法的方案,仅有一列选取的个数会超过总个数的一半。

所以我们可以枚举超过总个数一半的那一列,然后设\(f[i][j][k]\)表示选取到第\(i\)行,枚举的超过一半的这一列选择了\(j\)个,其他列选择了\(k\)个的方案数。

那么这一列可以选择这一列,可以选择其他列,也可以不选。所以有方程

\[f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k]\times cnt[i][j]+f[i-1][j][k-1]\times (sum[i]-cnt[i][j])
\]

其中\(sum[i]=\sum^m_{j=1}cnt[i][j]\)

那么选取枚举的这一行超过一半,最终不合法的方案数就是

\[ans=\sum_{j>k}f[n][j][k]
\]

时间复杂度\(O(mn^3)\),这样就得到了\(84pts\)的超级足的暴力分。

然而我考场这都没写出来qwq

我们发现最终只要满足\(j>k\)就可以计算进答案,中间过程我们也只关心\(j,k\)的大小关系。

所以我们可以省去\(j,k\)那两维,设\(f[i][j]\)表示第\(i\)行,选择超过一半的这一列比其他列多选的个数为\(j\)的方案数。

那么就有方程

\[f[i][k]=f[i-1][k]+f[i-1][k-1]\times cnt[i][j]+(sum[i]-cnt[i][j])\times f[i-1][k+1]
\]

然后答案就是

\[ans=\sum^{n}_{i=1}f[n][i]
\]

这样我们就在\(O(n^2)\)的时间复杂度内求出了不合法的方案数。

总方案数很好计算,第\(i\)行有\(sum[i]\)种选择方案,再加上不选,所以总方案数就是

\[all=\Pi^{n}_{i=1}(sum[i]+1)
\]

注意还要排除全部不选的情况。所以最终答案就是\(all-ans-1\)。

时间复杂度\(O(mn^2)\)。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N=110,M=2010,MOD=998244353;
ll ans,all,f[N][N+N],cnt[N][M],sum[N];
int n,m; int main()
{
scanf("%d%d",&n,&m);
all=1;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
scanf("%lld",&cnt[i][j]);
sum[i]+=cnt[i][j];
}
all=((sum[i]+1)%MOD*all)%MOD;
}
for (int j=1;j<=m;j++)
{
f[0][N]=1;
for (int i=1;i<=n;i++)
for (int k=-n+N;k<=n+N;k++)
f[i][k]=(f[i-1][k]+f[i-1][k-1]*cnt[i][j]+(sum[i]-cnt[i][j])%MOD*f[i-1][k+1])%MOD;
for (int i=1;i<=n;i++)
ans=(ans+f[n][i+N])%MOD;
}
printf("%lld",((all-ans-1)%MOD+MOD)%MOD);
return 0;
}

【CSP-S 2019】【洛谷P5664】Emiya 家今天的饭【dp】的更多相关文章

  1. 洛谷P5664 Emiya 家今天的饭 问题分析

    首先来看一道我编的题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共 ...

  2. 洛谷P5664 Emiya 家今天的饭 题解 动态规划

    首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...

  3. 洛谷 P5664 Emiya 家今天的饭(84分)

    题目传送门 解题思路: 对于每一个列c,f[i][j][k]表示到第i行,第c列选了j个,其它列一共选了k个,然后我们读题意发现只要j>k,那就一定是不合法的,然后统计所有方案,减去所有不合法方 ...

  4. P5664 Emiya 家今天的饭

    题面 link 前言 去年把我做自闭的一道题,看了一眼题面,发现只有 t1 有点思路,结果写到一半发现自己读错题了,又只能花时间来重构,结果后面的暴力一点都没写(主要是自己当时不会) 然后,这道题还因 ...

  5. 括号树 noip(csp??) 2019 洛谷 P5658

    洛谷AC通道 本题,题目长,但是实际想起来十分简单. 首先,对于树上的每一个后括号,我们很容易知道,他的贡献值等于上一个后括号的贡献值 + 1.(当然,前提是要有人跟他匹配,毕竟题目中要求了,是不同的 ...

  6. 格雷码 CSP(NOIP??)2019 洛谷 P5657

    洛谷AC通道! 多年过后,重新来看这道D1T1,20min不到AC,再回忆起当初考场三小时的抓耳挠腮,不禁感慨万千啊!! 发篇题解记录一下. 思路:直接dfs模拟即可(二进制找规律是不可能的, 这辈子 ...

  7. 洛谷CF809C Find a car(数位DP)

    洛谷题目传送门 通过瞪眼法发现,\(a_{i,j}=(i-1)\text{ xor }(j-1)+1\). 二维差分一下,我们只要能求\(\sum\limits_{i=0}^x\sum\limits_ ...

  8. 【题解】洛谷P1169 [ZJOI2007] 棋盘制作(坐标DP+悬线法)

    次元传送门:洛谷P1169 思路 浙江省选果然不一般 用到一个从来没有听过的算法 悬线法: 所谓悬线法 就是用一条线(长度任意)在矩阵中判断这条线能到达的最左边和最右边及这条线的长度 即可得到这个矩阵 ...

  9. 洛谷 P2015 二叉苹果树(codevs5565) 树形dp入门

    dp这一方面的题我都不是很会,所以来练(xue)习(xi),大概把这题弄懂了. 树形dp就是在原本线性上dp改成了在 '树' 这个数据结构上dp. 一般来说,树形dp利用dfs在回溯时进行更新,使用儿 ...

随机推荐

  1. python基础 — 局部变量/全局变量

    变量作用区域 变量器作用的额代码范围称为变量的作用与,不同作用区域之间互不影响,函数每部定义的变量一般为局部变量,而不属于任何函数的变量一般为全局变量.所以我们在这里按变量的作用区域分为两类,全局变量 ...

  2. Governing sand(主席树/贪心)(2019牛客暑期多校训练营(第七场))

    示例:输入:25 1 11 10 125 1 23 2 3输出:12 题意:n种树,第i种树有P[i]颗,砍掉每颗树的代价是C[i], 高度是H[i].需要用最小的花费砍掉一些树,让最高的树超过一半. ...

  3. Java date日期类型,结束日期减去开始日期求两者时间差,精确到秒

    /** * @Author: * @Description: * @Date: 2019/4/10 19:01 * @Modified By: */ @Slf4j public class DateU ...

  4. Mybatis @Result注解的使用案例

    @Result注解的使用

  5. easy ui 常用控件配置

    table comboBox 下拉高度 panelHeight:'auto' textBox

  6. 阿里企业邮箱smtp设置

    阿里的邮箱没有SMTP授权码信息 SMTP服务器:smtp.mxhichina.com

  7. Attribute与Property关系

    总的来说,其实是HTML Attribute 与 DOM property之间的关系. 1 什么是Property? JS DOM Object对象有property.一个property可能是不同数 ...

  8. Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))

    off by one(栈)? 将源字符串复制到目标缓冲区可能会导致off by one 1.源字符串长度等于目标缓冲区长度. 当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上 ...

  9. 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片

    上一篇文章 实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 演示了如何将视频文件转换为yuv文件保存,现在要做的是如何将yuv文件利用OpenGLES渲染展示出图像画面.要将 ...

  10. SAP ABAP的CI/CD解决方案

    如今国外很多partners已经在尝试Jenkins + abapGit + 公有云搭建ABAP CI/CD环境了.ABAP系统的改动通过abapGit提交,触发Jenkins上部署的命令行脚本,脚本 ...