首页 > 其他分享 >P5664[CSP-S2019] Emiya 家今天的饭 (dp + 计数)

P5664[CSP-S2019] Emiya 家今天的饭 (dp + 计数)

时间:2022-09-05 20:36:44浏览次数:94  
标签:烹饪 P5664 int sum 菜品 食材 ans Emiya S2019

 

P5664[CSP-S2019] Emiya 家今天的饭 (dp + 计数)

题目传送门

题目大意:

给定一个大小为 \(n * m\) 的表格 , 其中 \(a_{i , j}\) 表示用第 \(i\) 种烹饪方式并且有第 \(j\) 种主要食材的不同菜品的数量,找出至少有一种菜品,每种菜品的烹饪方式不同且满足,所有的主要食材的出现次数不超过总菜品数的一半的方案数。

题目分析:
  • [\(1\)] : 因为每种菜品的烹饪方式均不同,那么我们想到可以枚举烹饪方式。

  • [\(2\)] : 正难则反。我们对于方案数可以很快速的求出总的方案数,那我么可以想到用总的方案数减去不符合的方案数。

  • [\(3\)] : 设总方案数为 \(ans\) , 那么我们先考虑每一行的方案数,对于每一行只能选取一种,故每行方案数为这种烹饪方式所能做的所有菜品,我们令 \(sum_i\) 为每行的总数量,那么 \(ans\) 是否等于 \(\prod_{i = 1} ^ n sum_i\) 呢? 答案是否定的,因为对于每一行我们还可以不选,所以 \(ans = \prod_{i = 1} ^ n ({sum_i +1})\) , 在 \(ans\) 中还包含了一个什么也不选的方案,所以还需要将 \(ans\) 减 \(1\)。

  • [\(4\)] : 考虑完第一个以及第二个条件,我们再来考虑不满足第三个条件的方案数,由于遍历有一定的顺序,所以我们考虑使用 \(dp\) 来求解 。

  • [\(5\)] : 首先我们考虑最暴力的做法,根据什么不好处理就将其放到状态中的方法, 我们令 \(f_{i , j, k , l}\) 为前 \(i\) 中烹饪方式中,选了 \(k\) 个菜品 , \(j\) 食材出现了 \(l\) 次的方案数。 那么很好得出: \(f_{i,j,k,l} = f_{i - 1 , j,k,l} + a_{i,j} * f_{i - 1,j,k - 1,l - 1} + (\Sigma_{x=1}^n a_{i,x} - a_{i,j}) * f_{i - 1,j,k - 1,l}\)。 其中 \(\Sigma_{x=1}^n a_{i,x} - a_{i,j}\) 可以变为 \(sum_i - a_{i,j}\)。所以 : \(f_{i,j,k,l} = f_{i - 1 , j,k,l} + a_{i,j} * f_{i - 1,j,k - 1,l - 1} + (sum_i - a_{i,j}) * f_{i - 1,j,k - 1,l}\)
    复杂度为 \(O(n^3m)\)

  • [\(6\)] : 根据转移式子我们可以发现,注意的复杂度已经降为 \(O(1)\) ,故我们考虑去优化状态,因为题目中要求最多的食材不超过所选菜品的一半,所以我们直接维护这种食材与其他食材的差即可 ,所以我们令 \(f_{i,j,k}\) 为前 \(i\) 中烹饪方式,\(j\) 食材的数量与其他所有食材的数量之差为 \(k\)。 那么转移方程为: \(f_{i,j,k} = f_{i - 1,j,k} + a_{i,j} * f_{i - 1,j,k - 1} + (sum_i - a_{i,j}) * f_{i - 1,j,k + 1}\),我们又发现每次转移时 \(j\) 是不发生变化的,所以我们考虑将 \(j\) 这一维去掉,我们可以在最外层枚举第 \(j\) 种食材,然后就降维了,最后我们只需要让 \(ans\) 见到所有 \(k > 0\) 的情况即可。

代码实现:

因为 \(k\) 可能会出现负的,所以我们让 \(k\) 都去加上 \(n\) 来保证 \(k\) 都是正的,其他细节见代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 998244353;
const int M = 2e3 + 7;
int a[200][M] , sum[200];
int n , m; 
int dp[200][500];
int get_id(int x) {//这里就是将 k 变为正的的
	return x + n + 1;
}
signed main () {
	ios::sync_with_stdio(0),cin.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; ++ i) for(int j = 1; j <= m; ++ j) {cin >> a[i][j];sum[i] += a[i][j];sum[i] %= mod;}
	int ans = 1;
	for(int i = 1; i <= n; ++ i) ans = (ans * (sum[i] + 1)) % mod;//求出总方案数
	ans = (ans - 1 + mod) % mod;//减掉一个都不选的
	for(int i = 1; i <= m; ++ i) {
		memset(dp , 0 , sizeof dp);
		dp[0][get_id(0)] = 1;//初值
		for(int j = 1; j <= n; ++ j) 
			for(int k = -1 * n; k <= n; ++ k) 
				dp[j][get_id(k)] = (dp[j - 1][get_id(k)] + a[j][i] * dp[j - 1][get_id(k - 1)] % mod + ((sum[j] + mod - a[j][i]) * dp[j - 1][get_id(k + 1)]) % mod) % mod;
		for(int k = 1; k <= n; ++ k) ans = (ans - dp[n][get_id(k)] + mod) % mod;
	}
	cout << ans;
	return 0;	
}

[========]

完结!

标签:烹饪,P5664,int,sum,菜品,食材,ans,Emiya,S2019
From: https://www.cnblogs.com/Love-yx/p/16659366.html

相关文章

  • vs2019编辑代码闪退解决方法
    错误应用程序名称:devenv.exe,版本:16.11.32802.440,时间戳:0x62e9f741错误模块名称:KERNELBASE.dll,版本:10.0.19041.1949,时间戳:0xa599bd99异常代码:0xe0434352错......
  • 在VS2019中配置OpenGL环境。(使用CMake方法)
    网上一大堆VS下配置OpenGL环境的,但是这些方法都是基于VS空项目,并没有利用Cmake来构建。而我之前的代码都是在Linux下使用cmake构建,所以为了更快的在VS下调试运行我的程序,所......
  • VS2019修改文件编码
    1.查看文件编码安装扩展,FileEncoding,就可以在文件窗口右下角查看到该文件的编码方式,同时也可以直接在此处修改。2.修改项目的文件编码使用editorconfig文件。在工具......
  • VS2019使用dbml数据文件
    1.场景:以前的项目数据库对象用的是dbml,但是因为VS使用的是2019,打开就没有图像了(只能手动写映射类对象属性)2.处理方式;安装【LINQtoSQL工具】和【EntityFramework6......
  • vs2019 配置 qt6
    1.下载qt6我的目录C:\Qt\6.3.1\msvc2019_64\binC:\Qt\6.3.1\msvc2019_64\includeC:\Qt\6.3.1\msvc2019_64\lib 2.下载vs2019 3.vs下载qt插件扩展》管理扩展。......
  • Vs2019 单元测试突然出现 Microsoft.VisualStudio.TestTools.UnitTesting 不识别
    Microsoft.VisualStudio.QualityTools.UnitTestFrameworkusingMicrosoft.VisualStudio.TestTools.UnitTesting;  这句代码编辑器无法识别,  同时 [TestClass] [T......
  • VS2019 调试技巧之附加进程
    VS2019调试技巧之附加进程C#创建服务并附加到进程进行调试步骤一:在任务栏右键-》》点击任务管理器-》》选择服务,找到启动的进程PID或者WIN+R进入cmd命令 输......
  • VS2019 git 提交忽略生成文件
    由于首次将代码移交至gitee时,没有注意,将一堆生成文件都提交到了码云上,如debug、release下的文件等等。提交时需要将这些文件忽略掉,那么应该怎么做呢?一、通过VS2019添加.g......
  • Win10+VS2019+Qt5.15.2下编译QCAD
    Win10+VS2019+Qt5.15.2下编译QCAD目录Win10+VS2019+Qt5.15.2下编译QCAD环境配置Qt安装VisualStudio2019安装QCAD编译Clone编译QCAD编译QtScripts插件运行问题总结参考......