当前位置: 首页 > news >正文

【01背包】[USACO09MAR] Cow Frisbee Team S

P2946 [USACO09MAR] Cow Frisbee Team S

在这里插入图片描述

分析

在常规的01背包问题中,有一个很明显的限制条件,常见的都是给出一个最大体积,然后我们根据这个体积限制条件结合物品个数来设计状态表示
请添加图片描述
那么这道题中限制条件是什么呢,如何看出这道题是01背包问题?题目中要求总能力必须是F的倍数,这就是限制条件。

请添加图片描述
如上图,如果我们直接枚举所有可能的能力总和,在时间和空间上都会超。因为这题的奶牛数量范围最大为2000,每头奶牛的能力最大为1e5,乘起来就得到了2e8级别的数字,这还只是j的范围。在f[i][j]中,再加上i的最大数量2000,整个dp数组就来到了4e11级别,想都不用想了。

那么怎么优化呢?这题要求总能力是F的倍数,它并不在乎总能力具体是多少,那么我们只需要枚举 j 到 F-1 的位置就可以了啊,每次计算能力都模F,这样整个 j 的数据范围就落在了 0 ~ 999,如下图。
请添加图片描述

但是这题有几个细节需要注意:

  • 在选第i个奶牛时,要用 j - a[i]%f,而不是用 j - a[i],因为我们用模运算的基本性质已经将总能力之和再%f转换成了每头奶牛的能力%f再相加,这样更方便计算状态转移方程

  • 状态转移方程的选当前奶牛情况中,j-a[i]%m有可能是负数,那么就面临数组越界访问,以及这个数有没有意义的讨论。实际上这个数是有意义的,根据同余理论,可以加上模数让这个负数补正,它们是等价的,意义也相同,在C++中采用模加模补正。
    在这里插入图片描述
    重中之重就是理解:我们需要的是余数值的等价性,而非具体的正负。
    详见:模运算的基本性质中的同余类
    那么负数是如何产生的呢,请看下图
    请添加图片描述

  • 注意 j 的范围是 0 ~ m(模数)- 1,取不到 m for(int j=0;j<m;j++)

  • f[0][0]初始化为1,f[0][0]本身是有意义的,它表示在0头牛中选出总能力模f后为0的方案数,什么都不选本身就符合条件,所以它的方案数为1。但是最后在取结果的时候,f[0][0]要排除掉,因为奶牛队伍中奶牛数量最少为1

  • 最终结果在f[n][0]中,0表示总能力和模f后为0,那么总能力就是f的倍数,符合题意

  • 这道题是不能使用一个数组来滚动进行空间优化的,因为j - a[i]在补正后有可能位于i-1行的任意位置,有可能在j的左边或者右边,就不能靠常规的逆序加一维数组来优化了。如果非要空间优化那就只能用两个数组来回倒,但这是这样就增加了时间消耗,所以如果不能使用一个数组来进行空间优化,一般就不要优化了,不然会有超时的风险。

题解

#include<iostream>using namespace std;const int N = 2010, M = 1010, MOD = 1e8; int a[N]; //f[i][j]表示在1~i个奶牛中,选出的奶牛的总能力模m后为j的,总方案数 
int f[N][M];
int n,m;int main()
{ cin >> n >> m;for(int i=1;i<=n;i++) cin >> a[i];f[0][0] = 1;for(int i=1;i<=n;i++){for(int j=0;j<m;j++) //j取不到m {f[i][j] = (f[i-1][j] + f[i-1][((j-a[i]%m)%m+m)%m]) % MOD;			}}	cout << f[n][0] - 1 << endl; //排除f[0][0] 奶牛队伍中奶牛数量>=1 return 0;
}
http://www.xdnf.cn/news/462817.html

相关文章:

  • 支付宝创建商家订单收款码(统一收单线下交易预创建).net开发的软件附带大型XML文件可以删除吗?AlipaySDKNet.OpenAPI.xml
  • Android Studio中Gradle中Task列表显示不全解决方案
  • 帧差法识别
  • Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
  • c/c++消息队列库RabbitMQ的使用
  • golang -- 认识channel底层结构
  • LLM Text2SQL NL2SQL 实战总结
  • set, multiset ,unordered_set; map, multimap, unordered_map
  • 【向量维度如何选择?】
  • 深入探索向量数据库:构建智能应用的新基础
  • linux dbus
  • print()函数详解:输出文字、变量与格式化
  • Windows 安装 Redis 的几种方式
  • 设计模式(基于Python3)
  • Python课程及开源项目推荐
  • 宣纸阁项目测试报告
  • 流程编辑器Bpmn与LogicFlow学习
  • 2025长三角数学建模C题完整思路
  • Python多线程
  • 计算机网络:什么是电磁波以及有什么危害?
  • 谷歌量子计算机:开启计算新纪元
  • C# 活动窗体截图:基于 Win32 API 的实现
  • 有效的括号
  • 【蓝桥杯省赛真题49】python偶数 第十五届蓝桥杯青少组Python编程省赛真题解析
  • ROS--NAVI DWA
  • 【c语言】动态内存分配
  • MySQL 迁移至 Doris 最佳实践方案
  • 低功耗实现方法思路总结
  • 策略模式-枚举实现
  • 如何判断一个网站后端是用什么语言写的