【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分的暴搜滚粗 ...
随机推荐
- 为什么每次登录要手动 source /etc/profile ...
由于执行顺序如下,故追个查看以下文件,看看是不是 JAVA_HOME, PATH 等环境变量在后面的文件中被重写覆盖了. 1. /etc/profile2. /etc/environment3. ~/ ...
- golang web框架 beego 学习 (六) request body和module的映射
router.go package routers import ( "gowebProject/controllers" "github.com/astaxie/bee ...
- Ubuntu下搜狗拼音输入法打不出汉字的解决方法
问题 (1)Ubuntu下,搜狗拼音输入法能启动(系统托盘处有图标),但是打不出汉字,打字时选框不正常. 或者 (2)Deepin下,搜狗输入法无法启动,托盘处不显示图标,fcitx运行正常(这个可以 ...
- redis 启动配置文件加载报错 service redis does not support chkconfig
# chkconfig: # description:Redis is a persistent key-value database 网上资料 上面的注释的意思是,redis服务必须在运行级2,3, ...
- vue中的$attrs属性和inheritAttrs属性
一.vue中,默认情况下,调用组件时,传入一些没有在props中定义的属性,会把这些“非法”属性渲染在组件的根元素上(有一些属性除外),而这些“非法”的属性会记录在$attrs属性上. 二.如何控制不 ...
- 使用Rabbit MQ消息队列
使用Rabbit MQ消息队列 综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息 ...
- 【转载】49个CSS知识点
01.[负边距]
- Jmeter plugins 之 Perfmon Metrics Collector(服务器性能监控)
客户端(Jmeter端) 1.安装plugins manager,然后安装 2.添加listener-(第1步成功后才可看到此功能) 服务端:(要监控的服务器) 1.下载ServerAgent,并 ...
- 串口调试助手--Qt
串口调试助手----------该程序使用Qt框架,C ++语言编译而成 项目文件介绍: main.cpp 该文件为该程序的入口程序 mainwindow.h 该文件为该程序的主要声明部分 mainw ...
- 通过jquery触发select自身的change事件
###通过jquery触发select自身的change事件 1.通过js来去触发select的change事件 代码如下:包含了html部分和js部分 //html部分 <select cla ...