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

P3622 动物园-状压

P3622 动物园-状压

[APIO2007] 动物园

题目大意

问题描述:
有一个环形动物园,共有 N 个围栏(环形排列),每个围栏里有一种动物。有 C 个小朋友,每个小朋友会从某个围栏 E 开始,连续看到 5 个围栏(顺时针方向)。
每个小朋友有喜欢的动物和害怕的动物(都在他看到的 5 个围栏中)。

小朋友高兴的条件是:

  1. 至少有一个他害怕的动物被移走;
  2. 至少有一个他喜欢的动物没有被移走。

目标: 选择移走哪些动物,使得高兴的小朋友数量最多


输入格式

N C
E1 F1 L1 X1 X2 ... XF1 Y1 Y2 ... YL1
  • 第 1 行N(围栏数,10 ≤ N ≤ 10^4),C(小朋友数,1 ≤ C ≤ 5×10^4)。
  • 接下来 C 行:每行描述一个小朋友:
    • E:该小朋友看到的第一个围栏编号(1 ≤ E ≤ N)。
    • F:害怕的动物数。
    • L:喜欢的动物数。
    • 接着 F 个整数:害怕的动物所在围栏编号。
    • 接着 L 个整数:喜欢的动物所在围栏编号。
    • 所有 XY 都是该小朋友能看到的 5 个围栏中的,且互不相同。

输出格式

一个整数:最多能让多少个小朋友高兴


解题思路

关键观察

  1. 每个小朋友只能看到 5 个围栏,这个数字很小,提示我们可以用状态压缩
  2. 相邻的小朋友看到的围栏有重叠部分(4 个),因此状态可以传递。
  3. 由于是环形,首尾状态必须一致(最后 4 个围栏与开头 4 个围栏对应)。

状态设计

dp[i][j] 表示处理到第 i 个围栏,且从第 i 个围栏开始的 5 个围栏的状态为 j(二进制表示,1 表示保留,0 表示移走)时,最多能高兴的小朋友数。

状态转移

当前状态的后 4 位必须等于前一个状态的前 4 位(因为重叠):

dp[j][k] = max(dp[j-1][(k&15)<<1], dp[j-1][(k&15)<<1|1]) + cnt[j][k]

其中 15 的二进制是 1111,用于取后 4 位。

预处理

对于每个小朋友,我们记录他站在位置 st 时,对 5 个围栏的每种状态 j 是否高兴:

  • 如果 (害怕的动物集合) ∩ (移走集合) ≠ ∅(喜欢的动物集合) ∩ (保留集合) ≠ ∅,则该小朋友高兴。
  • 预处理 cnt[st][j] 表示在位置 st,状态为 j 时高兴的小朋友数。

环形处理

枚举初始状态 i(0 到 31),设置 dp[0][i] = 0,然后进行 DP。最后检查 dp[n][i] 是否与初始状态一致,取最大值。


代码实现

#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn = 5e4+10;
constexpr int maxm = 3e6+10;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;int n,m,ans;
int cnt[maxn][35];
int dp[maxn][35];signed main()
{#ifndef ONLINE_JUDGEfreopen("cjdl.in","r",stdin);freopen("cjdl.out","w",stdout);#endif // ONLINE_JUDGEscanf("%lld%lld",&n,&m);for(int i=1,st,f,l ;i<=m;++i)// st,fear,love{scanf("%lld%lld%lld",&st,&f,&l);int fear=0;int love=0;for(int j=1,pos ;j<=f;++j){scanf("%lld",&pos);fear |= (1<<(pos-st+n)%n);// 高位离st远}for(int j=1,pos ;j<=l;++j){scanf("%lld",&pos);love |= (1<<(pos-st+n)%n);}for(int j=0;j<32;++j)// 31==0b11111   0-zou 1-liu{if((fear & ~j) || (love & j)){++cnt[st][j];}}}for(int i=0;i<32;++i){memset(dp,128,sizeof(dp[0])*(n+1));dp[0][i]=0;// 0->1for(int j=1;j<=n;++j){for(int k=0;k<32;++k){dp[j][k]=max(dp[j-1][(k&15)<<1],dp[j-1][(k&15)<<1|1])+cnt[j][k];// 15=0b1111,qu hou 4 wei// 取当前的近4位,枚举上个位置的第一位}}ans=max(ans,dp[n][i]);// 1 from 0_i ,n->1 <=> n==0_i}printf("%lld",ans);return 0;
}

复杂度分析

  • 时间复杂度:O(N × 32 × 2) = O(64N),可以通过。
  • 空间复杂度:O(N × 32),在约束范围内。

http://www.jsqmd.com/news/36540/

相关文章:

  • candy P14328: dp优化
  • 配对序列P11187: 线性dp
  • 2025年新疆广告公司权威推荐榜单:geo服务商/广告加盟/营销推广公司机构精选
  • 计算机毕设java的仓库管理系统 基于Java的智能仓库管理平台研发 Java技术驱动的仓库信息化管理系统设计与实现
  • 吴恩达深度学习课程二: 改善深层神经网络 第二周:优化算法(三)Momentum梯度下降法
  • 2025年大棚专用农膜供应商权威推荐榜单:双色大棚膜/大棚eva农膜/三层共挤大棚膜源头厂家精选
  • 【GitHub每日速递 20251110】开源AI编码神器OpenCode来袭!多平台安装,多模型适配,终端体验拉满
  • Gitee战略升级:从代码托管到AI驱动的工程效率平台
  • springboot项目上传到gitlab
  • 2025年重庆抖音推广机构推荐榜单:杰诚智享领衔行业前沿
  • Oracle OGG日常运维命令都在这里了。
  • flask: 报错:ImportError: cannot import name secure_filename from werkzeug
  • 2025年立式护散炉定制厂家权威推荐榜单:8英寸立式退火炉/立式合金炉/磷扩散炉源头厂家精选
  • 详细介绍:物联网常见通信Cat-1、NB-IoT、Cat-4、LoRa
  • 在Tuanjie引擎中使用自定义Webview
  • 2025年伸缩门生产厂家综合排名前十权威推荐
  • 洛阳伸缩门公司哪家强?2025年排名
  • 2025年11月中国伸缩门制造企业推荐排行榜单:智能出入管理解决方案权威指南
  • 100% 用 AI 做完一个新项目,从 Plan 到 Finished 我学到了这些
  • Gitee:构建国产化DevSecOps生态的领航者
  • 2025年重庆互联网公司排行榜单:诚信服务商top10
  • 小程序逆向调试分析学习
  • 2025年成都镀锌桥架厂家综合实力排行榜前十强权威发布
  • 2025年重庆互联网营销推荐排行榜
  • 2025年11月重庆互联网代运营服务推荐:专业团队
  • 大模型教程资源分享
  • 2025年西南铝单板工厂排行榜:top10实力厂家推荐
  • 2025年天然气热风炉供货厂家权威推荐榜单:燃气热风机/燃气热风炉/直燃式燃气热风炉源头厂家精选
  • 2025年山茶叶礼盒供货厂家权威推荐榜单:碧螺红茶礼盒/碧螺红茶/碧螺春茶叶礼盒源头厂家精选
  • IntelliJ IDEA 2025.2.4 11月最新版 安装、授权、使用说明