【NOIP/CSP2019】D2T1 Emiya 家今天的饭
这个D2T1有点难度啊
原题:


花了我一下午的时间,作为D2T1的确反常
条件很奇怪,感觉不太直观,于是看数据范围先写了个暴力
写暴力的时候我就注意到了之前没有仔细想过的点,烹饪方式必须不同
虽然a很大,但是n只有100,即总菜数比较小
而且虽然m和a都很大,但是一种方法只能做一道菜,即选一种食材
所以搜索枚举每种方法选哪种食材,最后检查方案是否满足条件
这样可以拿到32分
需要注意到一点很关键的性质
不管什么方案,最多只有一个食材能超过n/2,看到n/2要敏感
那么如果无视n/2的限制,直接dp就vans了,接下来只需要去掉不合法的方案
枚举哪一种食材超过n/2,可以发现此时食材只有两种,枚举到的食材和其他的食材
需要表达的状态数大大减少
设计状态,f[i][j][k]表示直到第i种方式,总共选了j道菜,其中k道菜用当前枚举食材
这样可以拿到82分
然后就不会了233
这个递推又没有决策,咋优化啊
本着单个题目思考时间不能过长的原则,观摩了python96的题解:
https://blog.csdn.net/weixin_37517391/article/details/103110646
立刻点化233
确实不太好想,果然适时看题解效率更高
我们记录状态的时候不必记录两类食材的数量,只需记录二者差值即可
只要差值相同,不同的数量对于合法性的判断都是等价的
那么以前的3维dp就优化到2维,可以ac了
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long
const int mo=;
int rd(){int z=,mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mk;
}
int n,m,a[][];
LL ans=;
int cnt[];
LL s[];
LL f7[][][];
LL f[][];
bool chck(int x){
if(!x) return false;
//注意x=0时必须特判,因为此时cnt也全是0,下面条件不会成立
for(int i=;i<=m;++i)if(cnt[i]>x/) return false;
return true;
}
void dfs(int x,int y,LL z){
if(x==n+){
if(chck(y)) ans=(ans+z)%mo;
return ;
}
dfs(x+,y,z);
for(int i=;i<=m;++i)if(a[x][i]){
++cnt[i];
dfs(x+,y+,z*a[x][i]%mo);
--cnt[i];
}
}
LL gan(int x){
memset(f7,,sizeof(f7));
f7[][][]=;
for(int i=;i<=n;++i)for(int j=;j<=i;++j)for(int k=;k<=j;++k){
f7[i][j][k]=f7[i-][j][k];
if(j && k) f7[i][j][k]=(f7[i][j][k]+f7[i-][j-][k-]*a[i][x]%mo)%mo;
if(j) f7[i][j][k]=(f7[i][j][k]+f7[i-][j-][k]*(s[i]-a[i][x])%mo)%mo;
}
LL bwl=;
for(int i=;i<=n;++i)for(int j=i/+;j<=i;++j) bwl=(bwl+f7[n][i][j])%mo;
return bwl;
}
LL ganisok(int x){
memset(f,,sizeof(f));
f[][n]=;
for(int i=;i<=n;++i)for(int j=;j<=n+n;++j){
f[i][j]=f[i-][j];
if(j) f[i][j]=(f[i][j]+f[i-][j-]*a[i][x]%mo)%mo;
if(j<n+n) f[i][j]=(f[i][j]+f[i-][j+]*(s[i]-a[i][x]%mo))%mo;
}
LL bwl=;
for(int i=n+;i<=n+n;++i) bwl=(bwl+f[n][i])%mo;
return bwl;
}
int main(){
//freopen("ddd.in","r",stdin);
cin>>n>>m;
for(int i=;i<=n;++i)for(int j=;j<=m;++j) a[i][j]=rd();
if(n<= && m<=){
dfs(,,);
cout<<ans<<endl;
}
else if(n<= && m<=){
for(int i=;i<=n;++i){
s[i]=;
for(int j=;j<=m;++j) s[i]=(s[i]+a[i][j])%mo;
}
LL bwl=;
for(int i=;i<=n;++i) bwl=bwl*(s[i]+)%mo;
bwl-=;
for(int i=;i<=m;++i) bwl=(bwl-gan(i))%mo;
cout<<(bwl%mo+mo)%mo<<endl;
}
else{
for(int i=;i<=n;++i){
s[i]=;
for(int j=;j<=m;++j) s[i]=(s[i]+a[i][j])%mo;
}
LL bwl=;
for(int i=;i<=n;++i) bwl=bwl*(s[i]+)%mo;
bwl-=;
for(int i=;i<=m;++i) bwl=(bwl-ganisok(i))%mo;
cout<<(bwl%mo+mo)%mo<<endl;
}
return ;
}
【NOIP/CSP2019】D2T1 Emiya 家今天的饭的更多相关文章
- 【CSP-S 2019】D2T1 Emiya 家今天的饭
Description 传送门 Solution 算法1 32pts 爆搜,复杂度\(O((m+1)^n)\) 算法2 84pts 裸的dp,复杂度\(O(n^3m)\) 首先有一个显然的性质要知道: ...
- 洛谷P5664 Emiya 家今天的饭 问题分析
首先来看一道我编的题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共 ...
- 洛谷P5664 Emiya 家今天的饭 题解 动态规划
首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...
- CSP2019 Emiya 家今天的饭 题解
这题在考场上只会O(n^3 m),拿了84分.. 先讲84分,考虑容斥,用总方案减去不合法方案,也就是枚举每一种食材,求用它做超过\(\lfloor \frac{k}{2} \rfloor\) 道菜的 ...
- csp2019 Emiya家今天的饭题解
qwq 由于窝太菜了,实在是不会,所以在题解的帮助下过掉了这道题. 写此博客来整理一下思路 正文 传送 简化一下题意:现在有\(n\)行\(m\)列数,选\(k\)个数的合法方案需满足: 1.一行最多 ...
- CSP2019 Emiya 家今天的饭
Description: 有 \(n\) 中烹饪方法和 \(m\) 种食材,要求: 至少做一种菜 所有菜的烹饪方法各不相同 同种食材的菜的数量不能超过总菜数的一半 求做菜的方案数. Solution1 ...
- 【CSP-S 2019】【洛谷P5664】Emiya 家今天的饭【dp】
题目 题目链接:https://www.luogu.org/problem/P5664 Emiya 是个擅长做菜的高中生,他共掌握 \(n\) 种烹饪方法,且会使用 \(m\) 种主要食材做菜.为了方 ...
- Emiya家今天的饭 NOIP2019 (CSP?) 类DP好题 luoguP5664
luogu题目传送门! 首先,硬求可行方案数并不现实,因为不好求(去年考场就这么挂的,虽然那时候比现在更蒟). 在硬搞可行方案数不行之后,对题目要求的目标进行转换: 可行方案数 = 总方案数 - 不合 ...
- [CSP-S2019]Emiya 家今天的饭 题解
CSP-S2 2019 D2T1 很不错的一题DP,通过这道题学到了很多. 身为一个对DP一窍不通的蒟蒻,在考场上还挣扎了1h来推式子,居然还有几次几乎推出正解,然而最后还是只能打个32分的暴搜滚粗 ...
随机推荐
- 使用layui的form.on绑定select选中事件, form.on()不执行的原因分析
使用layui的form.on绑定select选中事件中, form.on()不执行, 主要原因有 1, select标签中没有写lay_filter属性,用来监听 <select id=&qu ...
- redis key 空闲(一)
语法: redis 127.0.0.1:6379> COMMAND KEY_NAME 实例: redis 127.0.0.1:6379[1]> select 2 OK redis 127. ...
- Core JSON及JSON解析
JSON (JavaScript Object Notation) 是一种基于文档的标准数据交换格式,它可以让应用程序通过网络交换数据.JSON独立于编程语言(Ruby, Java/EE, JavaS ...
- idea用maven创建web项目(详细)
引用:http://blog.csdn.net/u010361662/article/details/50605099 欢迎添加微信
- jQuery禁用input历史选择
$("#id").attr("autocomplete", "off");
- python set集合(16)
在python变量中除了以前文章所提到的整形int / 浮点数float / 布尔值bool / 列表list / 字典dict 之外,还有一个类型我们还没有做详细介绍,这个变量类型就是集合set. ...
- python不定长参数 *argc,**kargcs(19)
在 python函数的声明和调用 中我们简单的了解了函数的相关使用,然而在函数传递参数的时候,我们埋下了一个坑,关于不定长参数的传递我们还没有讲,今天这篇文章主要就是讲解这个问题. 一.函数不定长参数 ...
- [LuoguP1155]双栈排序_二分图_bfs
双栈排序 题目链接:https://www.luogu.org/problem/P1155 数据范围:略. 题解: 神仙题. 就第一步就够劝退了. 这个二分图非常不容易,首先只有两个栈,不是属于一个就 ...
- 【转帖】一文看懂docker容器技术架构及其中的各个模块
一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...
- 【规律】Cunning Friends
Cunning Friends 题目描述 Anthony and his friends Ben and Chris decided to play a game. They have N piles ...