CSP2019 Emiya 家今天的饭
Description:
有 \(n\) 中烹饪方法和 \(m\) 种食材,要求:
- 至少做一种菜
- 所有菜的烹饪方法各不相同
- 同种食材的菜的数量不能超过总菜数的一半
求做菜的方案数。
Solution1:考虑 DP
先容斥一下,答案为忽略第三个条件所得的方案数减去每一种食材超过一半的方案数之和。
忽略掉第三个条件之后答案显然是
\]
减去 1 是去掉一道菜都不做的方案。
枚举每一列超过一半的情况,显然,除这一列外,其他 \(n-1\) 列是一样的。那么对于第 \(col\) 列,设 \(f_{i,j,k}\) 表示前 \(i\) 行,第 \(col\) 列选 \(j\) 个且其他列选 \(k\) 个的方案数。则:
\]
此时的复杂度是 ,\(O(m)\) 的枚举 \(col\) * \(O(n^3)\) 的 \(DP\), = \(O(mn^3)\) ,可以得到 84pts 的好成绩了
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 101;
const int M = 2001;
const int mod = 998244353;
ll n,m;
ll s[N],a[N][M],f[N][N][N];
ll ans=1;
void init()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
scanf("%lld",&a[i][j]);
s[i]=(s[i]+a[i][j])%mod;
}
ans=(ans*(s[i]+1))%mod;
}
ans=(mod-1+ans)%mod;
}
int main()
{
init();
for(int col=1;col<=m;++col)
{
memset(f,0,sizeof(f));
f[0][0][0]=1;
for(int i=1;i<=n;++i)
{
for(int j=0;j<=i;++j)
{
for(int k=0;k<=i-j;++k)
{
f[i][j][k]=f[i-1][j][k]+f[i-1][j-1][k]*a[i][col]+f[i-1][j][k-1]*(s[i]-a[i][col]);
f[i][j][k]=(f[i][j][k]%mod+mod)%mod;
}
}
}
for(int j=1;j<=n;++j)
{
for(int k=0;k<=n-j;++k)
{
if(k<j) ans=((ans-f[n][j][k])%mod+mod)%mod;
}
}
}
printf("%lld\n",ans);
return 0;
}
Solution2:考虑优化
然后我们发现我们并不关心j和k的具体值。我们只关心他们的差。所以我们可以把后两维压缩成一维。
设 \(f_{i,j}\) 表示前 \(i\) 行,第 \(col\) 列比其他列多选 \(j\) 个的方案数。则:
\]
此时的复杂度是 ,\(O(m)\) 的枚举 \(col\) * \(O(n^2)\) 的 \(DP\), = \(O(mn^2)\) ,可以得到 100pts 的好成绩了
这里有一个小技巧就是把每个j都加上n,避免数组负下标的出现。
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 101;
const int M = 2001;
const int mod = 998244353;
ll n,m;
ll s[N],a[N][M],f[N][N*2];
ll ans=1;
void init()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
scanf("%lld",&a[i][j]);
s[i]=(s[i]+a[i][j])%mod;
}
ans=(ans*(s[i]+1))%mod;
}
ans=(mod-1+ans)%mod;
}
int main()
{
init();
for(int col=1;col<=m;++col)
{
memset(f,0,sizeof(f));
f[0][n]=1;
for(int i=1;i<=n;++i)
{
for(int j=n-i;j<=n+i;++j)//注意dp的范围!
{
f[i][j]=f[i-1][j]+f[i-1][j-1]*a[i][col]+f[i-1][j+1]*(s[i]-a[i][col]);
f[i][j]=(f[i][j]%mod+mod)%mod;
}
}
for(int j=1;j<=n;++j)
{
ans=((ans-f[n][n+j])%mod+mod)%mod;
}
}
printf("%lld\n",ans);
return 0;
}
Question:
DP的取值范围问题还是不清楚。
CSP2019 Emiya 家今天的饭的更多相关文章
- CSP2019 Emiya 家今天的饭 题解
这题在考场上只会O(n^3 m),拿了84分.. 先讲84分,考虑容斥,用总方案减去不合法方案,也就是枚举每一种食材,求用它做超过\(\lfloor \frac{k}{2} \rfloor\) 道菜的 ...
- csp2019 Emiya家今天的饭题解
qwq 由于窝太菜了,实在是不会,所以在题解的帮助下过掉了这道题. 写此博客来整理一下思路 正文 传送 简化一下题意:现在有\(n\)行\(m\)列数,选\(k\)个数的合法方案需满足: 1.一行最多 ...
- 洛谷P5664 Emiya 家今天的饭 问题分析
首先来看一道我编的题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共 ...
- 洛谷P5664 Emiya 家今天的饭 题解 动态规划
首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...
- 【NOIP/CSP2019】D2T1 Emiya 家今天的饭
这个D2T1有点难度啊 原题: 花了我一下午的时间,作为D2T1的确反常 条件很奇怪,感觉不太直观,于是看数据范围先写了个暴力 写暴力的时候我就注意到了之前没有仔细想过的点,烹饪方式必须不同 虽然a很 ...
- 【CSP-S 2019】【洛谷P5664】Emiya 家今天的饭【dp】
题目 题目链接:https://www.luogu.org/problem/P5664 Emiya 是个擅长做菜的高中生,他共掌握 \(n\) 种烹饪方法,且会使用 \(m\) 种主要食材做菜.为了方 ...
- 【CSP-S 2019】D2T1 Emiya 家今天的饭
Description 传送门 Solution 算法1 32pts 爆搜,复杂度\(O((m+1)^n)\) 算法2 84pts 裸的dp,复杂度\(O(n^3m)\) 首先有一个显然的性质要知道: ...
- Emiya 家今天的饭
\(dp_{i,j,k}\)表示前\(i\)种烹饪方法,假设最多的是食材\(j\),食材\(j\)比其他食材多\(k\)次出现 其中\(i \in [1,n],j \in [1,m],k \in [- ...
- 【JZOJ6433】【luoguP5664】【CSP-S2019】Emiya 家今天的饭
description analysis 首先可以知道不符合要求的食材仅有一个,于是可以容斥拿总方案数减去选不合法食材的不合法方案数 枚举选取哪一个不合法食材,设\(f[i][j]\)表示到第\(i\ ...
随机推荐
- 一些基础但有趣的shell脚本
一.打印9*9乘法表 #!/bin/bash for i in `seq 9` do for j in `seq $i` do echo -n "$i*$j=$[i*j]" don ...
- Django框架之Filters(过滤器)、母版的使用
在Django的模板语言中,通过使用 过滤器 来改变变量的显示. 过滤器的语法: {{ value|filter_name:参数 }} 使用管道符"|"来应用过滤器. 注意事项: ...
- 喵星之旅-狂奔的兔子-rabbitmq的java客户端使用入门
一.简介 RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件). 消息队列都涉及的生产者消费者模型,不做详解,本文只作为快速使用的参考文档. 消息队列主要有点 ...
- Java进阶学习(1)之类与对象(上)
package com.study; //自动售卖机 public class vmachine { private int price = 80; private int balance; priv ...
- Java JDK 1.5 1.6 1.7 新特性整理
Java JDK 1.5的新特性 1.泛型 List<String> strs = new ArrayList<String>();//给集合指定存入类型,上面这个集合在存入数 ...
- java用JSONObject生成json
Json在前后台传输中,是使用最多的一种数据类型.json生成的方法有很多,自己只是很皮毛的知道点,用的时候,难免会蒙.现在整理下 第一种: import net.sf.json.JSONArray; ...
- dropna fillna
# NaN 浮点类型 np.nan+1 =>nan Python type(None) // NoneType类型 不能参与运算 import pandas as pd from pand ...
- webpack中使用babel
step one: https://babeljs.io/setup Choose your tool (try CLI) select webpack Step two: npm install - ...
- ICCV2019 oral:Wavelet Domain Style Transfer for an Effective Perception-distortion Tradeoff in Single Image Super-Resolution
引言 基于低分辨率的图像恢复高分辨图像具有重要意义,近年来,利用深度学习做单张图像超分辨主要有两个大方向:1.减小失真度(distortion, 意味着高PSNR)的图像超分辨,这类方法主要最小化均方 ...
- vue 中 限制 input 输入数字、小数位数等
限制小数位数 <input type="number" @keydown="handleInput2" placeholder="请输入或查看& ...