作为提高组d2t1d2t1d2t1,比去年难
所以这道题我打的特别的差

32pts

这道题我们很显然可以看到可以打一个暴力
复杂度o(n∗n!)o(n*n!)o(n∗n!)
我考场上就达到了这里——我太菜了

void dfs(int u,ll plus){if(u==n+1){if(!tot)return;Rep(i,1,m)if(cnt[i]>tot/2)return;ans=(ans+plus)%mod;return;}dfs(u+1,plus);Rep(i,1,m)if(a[u][i]){cnt[i]++;tot++;dfs(u+1,plus*a[u][i]%mod);tot--;cnt[i]--;}
}int main()
{read(n),read(m);Rep(i,1,n)Rep(j,1,m)read(a[i][j]);dfs(1,1);printf("%lld\n",ans);return 0;
}

因为每一行只能选一个,所以我们可以每行爆搜找选哪个(或者不选),随后判断行不行

64 pts

这道题一拿到题就觉得是dpdpdp,但是没想出来转移方程,想要拿到64分,我们需要把mmm=2,3的情况拆成两种来讨论,当m=2m=2m=2时,用f[i][j][k]f[i][j][k]f[i][j][k]表示第iii行,第一种食材用了jjj次,第二种用了kkk次,可以显然得到一个转移方程f[i][j][k]=sum{f[i−1][j][k],f[i−1][j−1][k]∗a[i][1],f[i−1][j][k−1]∗a[i][2]}f[i][j][k]=sum\{f[i-1][j][k],f[i-1][j-1][k]*a[i][1],f[i-1][j][k-1]*a[i][2]\}f[i][j][k]=sum{f[i−1][j][k],f[i−1][j−1][k]∗a[i][1],f[i−1][j][k−1]∗a[i][2]}
当m=3m=3m=3时就是四位dpdpdp

if(m==2){f[0][0][0]=1;Rep(i,1,n)Rep(j,0,i)Rep(k,0,i){if(j+k>i)break;if(j>=1)f[i][j][k]+=f[i-1][j-1][k]*a[i][1],f[i][j][k]%=mod;if(k>=1)f[i][j][k]+=f[i-1][j][k-1]*a[i][2],f[i][j][k]%=mod;f[i][j][k]+=f[i-1][j][k],f[i][j][k]%=mod;}Rep(i,1,n)           ans=(ans+f[n][i][i])%mod;printf("%lld\n",ans);
}
if(m==3){g[0][0][0][0]=1;Rep(i,1,n)Rep(j,0,n)Rep(k,0,n)Rep(l,0,n){if(j+k+l>i)break;if(j>=1)g[i][j][k][l]+=g[i-1][j-1][k][l]*a[i][1],g[i][j][k][l]%=mod;if(k>=1)g[i][j][k][l]+=g[i-1][j][k-1][l]*a[i][2],g[i][j][k][l]%=mod;if(l>=1)g[i][j][k][l]+=g[i-1][j][k][l-1]*a[i][3],g[i][j][k][l]%=mod;g[i][j][k][l]+=g[i-1][j][k][l],g[i][j][k][l]%=mod;}Rep(i,0,n)Rep(j,0,n)Rep(k,0,n){int tot=i+j+k;if(i>tot/2||j>tot/2|k>tot/2||tot==0)continue;ans+=g[n][i][j][k];ans%=mod;   }printf("%lld\n",ans);
}

84pts

我们换一种想法,我们把所有可能的情况先算出来,然后再把不符合条件的都减去,怎么算减去的呢,我们可以想到超过一半的只可能有一种菜,我们先循环那种菜再第几列(col),其他的看成一种菜,那么我们设计状态f[i][j][k]f[i][j][k]f[i][j][k]表示前iii道菜,超过一半的菜有jjj道,剩下的选了kkk道,那么转移方程就是f[i][j][k]=sum{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]=sum\{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]=sum{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])}

ans=1;
Rep(i,1,n){Rep(j,1,m)s[i]=(s[i]+a[i][j])%mod; ans=ans*(s[i]+1)%mod;
}
Rep(col,1,m){memset(h,0,sizeof(h));h[0][0][0]=1;Rep(i,1,n)Rep(j,0,n)Rep(k,0,n){if(j+k>i)break;if(j>=1)h[i][j][k]+=h[i-1][j-1][k]*a[i][col],h[i][j][k]%=mod;if(k>=1)h[i][j][k]+=h[i-1][j][k-1]*(s[i]-a[i][col]),h[i][j][k]%=mod;h[i][j][k]+=h[i-1][j][k],h[i][j][k]%=mod;  }Rep(i,0,n)Rep(j,0,n){int tot=i+j;if(tot>n)continue;if(i<=tot/2)continue;ans=(ans-h[n][i][j]+mod)%mod;   }
}
printf("%lld\n",(ans-1+mod)%mod);

100pts

我们发现,我们最后统计的时候是和jjj,kkk没有关系的,我们只要知道他们的差就可以了,所以我们可以优化掉一维,复杂度变成了O(n2m)O(n^2m)O(n2m),可以过啦!
转移就变成了f[i][j]=sum{f[i−1][j],f[i−1][j−1]∗a[i][col],f[i−1][j+1]∗(s[i]−s[i][col])}f[i][j]=sum\{f[i-1][j],f[i-1][j-1]*a[i][col],f[i-1][j+1]*(s[i]-s[i][col])\}f[i][j]=sum{f[i−1][j],f[i−1][j−1]∗a[i][col],f[i−1][j+1]∗(s[i]−s[i][col])}但是第二维有可能是负的,所以要整体平移

# include <cstdio>
# include <algorithm>
# include <cstring>
# include <cmath>
# include <climits>
# include <iostream>
# include <string>
# include <set>
# include <map>
# include <queue>
# include <stack>
# include <cctype>
# include <cstdlib>
# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=5e3+5;const int ZERO=110;const int mod=998244353;typedef long long ll;template <typename T>void read(T &x){x=0;int f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';x*=f;
}int n,m;
int a[N][N];
ll f[45][45][45],g[45][45][45][45],s[N],h[45][45][45],dp[ZERO][2*ZERO+10];
int cnt[N],tot;
ll ans;void dfs(int u,ll plus){if(u==n+1){if(!tot)return;Rep(i,1,m)if(cnt[i]>tot/2)return;ans=(ans+plus)%mod;return;}dfs(u+1,plus);Rep(i,1,m)if(a[u][i]){cnt[i]++;tot++;dfs(u+1,plus*a[u][i]%mod);tot--;cnt[i]--;}
}int main()
{read(n),read(m);Rep(i,1,n)Rep(j,1,m)read(a[i][j]),a[i][j]%=mod;ans=1;Rep(i,1,n){Rep(j,1,m)s[i]=(s[i]+a[i][j])%mod;ans=ans*(s[i]+1)%mod;  }Rep(col,1,m){memset(dp,0,sizeof(dp));dp[0][ZERO]=1;Rep(i,1,n)for(int j=-1*i;j<=i;j++){if(j-1+ZERO>=0)dp[i][j+ZERO]+=dp[i-1][j-1+ZERO]*a[i][col],dp[i][j+ZERO]%=mod;dp[i][j+ZERO]+=dp[i-1][j+1+ZERO]*((s[i]-a[i][col]+mod)%mod),dp[i][j+ZERO]%=mod;dp[i][j+ZERO]+=dp[i-1][j+ZERO],dp[i][j+ZERO]%=mod;}Rep(i,1,n)ans=(ans-dp[n][i+ZERO]+mod)%mod;}printf("%lld\n",(ans-1+mod)%mod);return 0;
}

这道题其实64分不难,但是我特别的菜只打了暴力,所以只有32。。。
所以要好好练一练dpdpdp

[csp2019]Emiya家今天的饭相关推荐

  1. csp2019 Emiya 家今天的饭

    题目链接:https://www.luogu.com.cn/problem/P5664 去年考场上我很菜... 现在还是一样菜...... 题目抽象出来就是给你一个nnn行mmm列的矩阵(数表),可以 ...

  2. NOIP2019 Emiya家今天的饭

    NOIP2019 Emiya家今天的饭 ACM退役选手远程口胡 csf如今真的是太菜了,最后16分的做法愣是想了一下午 考虑使用容斥方法: 1 采用动态规划,先求出在无限制情况下,安排kkk种烹饪方法 ...

  3. 【CSP-S2019】D2T1 Emiya 家今天的饭

    CSP-S2019 D2T1 Emiya 家今天的饭 题目 题目描述 Emiya 是个擅长做菜的高中生,他共掌握 nnn 种烹饪方法,且会使用 mmm 种主要食材做菜.为了方便叙述,我们对烹饪方法从 ...

  4. [CSP day2T1]Emiya 家今天的饭

    Emiya 家今天的饭 题解 挺容易的一道dp,我们可以先考虑容斥.先加上不考虑菜数不超过一半的值,再减去超过一半的部分. 表示在前i种中选j个菜的总种类,这个dp很好想, 下面就是最重要的了. 表示 ...

  5. 2019CSP-S Day2T1 Emiya 家今天的饭 题解

    2019CSP-S Day2T1 Emiya 家今天的饭 题解 题目链接 我太菜了 64pts,m<=3m <= 3m<=3. 前64pts数据规模都差不多,因为mmm很小,考虑类似 ...

  6. Emiya家今天的饭

    题目来源: Emiya家的饭 代码 #include <bits/stdc++.h> using namespace std; const int MOD = 998244353; con ...

  7. CSP-S2019学习笔记:Emiya家今天的饭

    题目名称看样子灵感来自于日本动画片"卫宫家今天的饭". 这道题的难度是"提高+/省选-",算是提高组里比较难的.数据范围分的很细,解题方法跟数据范围关系比较大. ...

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

    太难惹!!! 文章目录 题目描述 一.分析 二.代码 总结 题目描述 Emiya 是个擅长做菜的高中生,他共掌握 n 种烹饪方法,且会使用 m 种主要食材做菜.为了方便叙述,我们对烹饪方法从 1∼n ...

  9. 洛谷P5664 Emiya 家今天的饭

    题目描述 Emiya 是个擅长做菜的高中生,他共掌握 nn 种烹饪方法,且会使用 mm 种主要食材做菜.为了方便叙述,我们对烹饪方法从 1 \sim n1∼n 编号,对主要食材从 1 \sim m1∼ ...

最新文章

  1. (备忘)Java数据类型中String、Integer、int相互间的转换
  2. 16 美元,黑客就能截获你的短信?
  3. warning C4251 needs to have dll-interface解决办法
  4. oracle v$access执行很慢,Oracle bug之v$access
  5. everyday words
  6. mongotemplate中save抛出异常_异常处理的三个好习惯 | Python 工匠
  7. Spring Boot笔记-拦截器相关(用户权限方面)
  8. python面试题Python2.x和Python3.x的区别
  9. ExecuteNonQuery()方法发即:是指执行非查询SQL命令,如:增、删、改等
  10. 【转】NPOI自定义单元格背景颜色
  11. 获取Excel数据及Sheet的方法
  12. 精确波段 抄底逃顶指标 通达信/东方财富 副图 源码
  13. mysql跨库查询语句mybatis_mybatis实现跨库多表查询
  14. PTC过流保护器件工作原理及选型方法
  15. laravel 请求出现 post The page has expired due to inactivity.
  16. opc ua 用哪种语言编写_OPC UA是个什么东东
  17. 谁“偷”走了我的雨伞
  18. 你要的所有数据源都在这里了!
  19. 【续】数学模型——人口增长模型
  20. 跳跃游戏(数组下标跳跃)

热门文章

  1. IDEA2020创建Maven项目卡在[INFO] Generating project in Batch mode状态(Maven配置阿里镜像)
  2. R语言21-多变量绘图
  3. C语言程序分析之长方形的体积(函数做法)
  4. 23.5.14总结(学习通项目)
  5. 不必追核心,前进途中路自明
  6. 强化学习之蒙特卡洛学习,时序差分学习理论与实战
  7. 信息技术的新潮流:云计算与大数据
  8. 1. mysql8.0.22安装及其简单使用
  9. NIO(一)--简介API介绍
  10. 第5章第18节:创建一个简单的Widget小组件 [SwiftUI快速入门到实战]