首页 > 其他分享 >动物园(APIO 2007)(状压DP)

动物园(APIO 2007)(状压DP)

时间:2024-02-23 19:11:37浏览次数:30  
标签:移走 状压 dp 围栏 动物 高兴 小朋友 APIO DP

动物园 题解

题目描述

原题来自:APIO 2007

新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围栏里有一种动物。如下图所示:

你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好的时光。但这并不是一件容易的事。有些小朋友喜欢某些动物,而有些小朋友则害怕某些动物。例如, Alex 喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的狮子。而 Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。

你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。

每个小朋友站在大围栏圈的外面,可以看到连续的 \(n\) 个围栏。你得到了所有小朋友喜欢和害怕的动物信息。当下面两处情况之一发生时,小朋友就会高兴:

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

例如,考虑下图中的小朋友和动物:

假如你将围栏 \(4\) 和 \(12\) 的动物移走。Alex 和 Ka-Shu 将很高兴,因为至少有一个他们害怕的动物被移走了。这也会使 Chaitanya 高兴,因为他喜欢的围栏 \(6\) 和 \(8\) 中的动物都保留了。但是,Polly 和 Hwan 将不高兴,因为他们看不到任何他们喜欢的动物,而他们害怕的动物都还在。这种安排方式使得三个小朋友高兴。

现在换一种方法,如果你将围栏 \(4\) 和 \(6\) 中的动物移走,Alex 和 Polly 将很高兴,因为他们害怕的动物被移走了。Chaitanya 也会高兴,虽然他喜欢的动物 \(6\) 被移走了,他仍可以看到围栏 \(8\) 里面他喜欢的动物。同样的 Hwan 也会因可以看到自己喜欢的动物 \(12\) 而高兴。唯一不高兴的只有 Ka-Shu。

如果你只移走围栏 \(13\) 中的动物,Ka-Shu 将高兴,因为有一个他害怕的动物被移走了,Alex, Polly, Chaitanya 和 Hwan 也会高兴,因为他们都可以看到至少一个他们喜欢的动物。所以有 \(5\) 个小朋友会高兴。这种方法使得了最多的小朋友高兴。

输入格式

输入的第一行包含两个整数 \(N\) , \(C\) ,用空格分隔。\(N\) 是围栏数,\(C\) 是小朋友的个数。围栏按照顺时针的方向编号为 \(1,2,3,\dots ,N\) 。

接下来的 \(C\) 行,每行描述一个小朋友的信息,以下面的形式给出:
$ E\ F\ L\ X_1 \ X_2 \dots \ X_F \ Y_1 \ Y_2 \dots Y_L $

其中: \(E\) 表示这个小朋友可以看到的第一个围栏的编号,换句话说,该小朋友可以看到的围栏为 $ E,E+1,E+2,E+3,E+4 $ 。注意,如果编号超过 \(N\) 将继续从 \(1\) 开始算。

\(F\) 表示该小朋友害怕的动物数。

\(L\) 表示该小朋友喜欢的动物数。

围栏 $ X_1 \ X_2 \dots \ X_F $ 中包含该小朋友害怕的动物。围栏
$ \ Y_1 \ Y_2 \dots Y_L $ 中包含该小朋友喜欢的动物。 $ X_1 \ X_2 \dots \ X_F \ Y_1 \ Y_2 \dots Y_L $ 是两两不同的整数,而且所表示的围栏都是该小朋友可以看到的。

小朋友已经按照他们可以看到的第一个围栏的编号从小到大的顺序排好了(这样最小的 \(E\) 对应的小朋友排在第一个,最大的 \(E\) 对应的小朋友排在最后一个)。

注意可能有多于一个小朋友对应的 \(E\) 是相同的。

样例输入 1

 14 5
 2 1 2 4 2 6
 3 1 1 6 4
 6 1 2 9 6 8
 8 1 1 9 12
 12 3 0 12 13 2

样例输出 1

 5

数据范围

$ 10 \le N \le 10^4 , 1 \le C \le 5 \times 10^4 ,1 \le E \le N $ 。

思路

真是一道状压好题,只是我当时不会。

当时的想法 $ dp[i][j] $ 表示第 \(i\) 个小朋友,所看到的动物状态为 \(j\)

显然(杜绝显然) \(i\) 和 \(i-1\) 看到的区间是可能重叠的,对于重叠部分,判断如果重叠不同,那么这种转移是不合法的,\(continue\) ,否则判断 \(i\) 区间的小孩能否满意,让他 \(happy\) ,$ dp[i][j]= \max { dp[i-1][k] }+1 $

唯一的问题是这是个环,最靠前和最靠后的小朋友看到的区间可能重合,要保证重叠部分相同才有意义,然后,太难实现,咕了。

正解

$ dp[i][j] $ 表示第 \(i\) 个围栏,向后 \(5\) 个围栏状态为 \(j\) 。

\[dp[i][j]=\max \{ dp[i-1][(j\&15)<<1],dp[i-1][((j\&15)<<1)|1] \} +num[i][j] \]

这里的位运算相当巧妙,自行理解。

$ num[i][j] $ 表示第 $ i $ 至 $ i+5 $ 个围栏,状态为 $ j $ ,会使 $ num[i][j] $ 个小朋友满足,预处理。

我们来看正确性,原有做法是因为不能保证首尾状态相同就死了,我们不妨枚举 \(n\) 的状态 \(i\) ,并将这一状态赋给 $ f[0][i]=0 $ ,由此将其传递给 $ f[1] $ ,这样保证 $ f[1] $ 和 $ f[n] $ 不会冲突。

枚举 \(n\) 的状态时要初始化为无穷小,只给合法的状态赋值,这样经过 $ max $ 后的解一定是合法的。

时间复杂度 $ O(2^{10}\times N) $

Code

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+100;
int n,c,a,b;
int start,f,l,t,fear,like;
int dp[N][1<<6],num[N][1<<6],ans;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    #endif
    scanf("%d%d",&n,&c);
    for(int i=1;i<=c;i++){
        scanf("%d%d%d",&start,&f,&l);
        fear=0;
        like=0;
        for(int j=1;j<=f;j++){
            scanf("%d",&t);
            t=(t-start+n)%n;//处理环
            fear|=(1<<t);
        }
        for(int j=1;j<=l;j++){
            scanf("%d",&t);
            t=(t-start+n)%n;
            like|=(1<<t);
        }
        for(int j=0;j<32;j++){
            if(((~j)&fear)||(j&like))num[start][j]++;
        }
    }
    for(int i=0;i<32;i++){
        memset(dp[0],128,sizeof(dp[0]));//初始化
        dp[0][i]=0;//合法状态
        for(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])+num[j][k];
            }
        }
        ans=max(ans,dp[n][i]);
    }
    printf("%d",ans);
}

DP好难,拜谢DP

标签:移走,状压,dp,围栏,动物,高兴,小朋友,APIO,DP
From: https://www.cnblogs.com/abnormal123/p/18030233

相关文章

  • 基于STM32F407MAC与DP83848实现以太网通讯三(STM32F407MAC配置以及数据收发)
    本章实现了基于STM32F407MAC的数据收发功能,通过开发板的RJ45接口连接网线到电脑,电脑使用Wiershark工具抓包验证。参考文档:DP83848IV英文DP83848EP中文STM32F4xx参考手册一、工程模板以及参考源码的获取工程源码我使用的正点原子的探索者开发板STM32F407(V2)参考源码:正点原子......
  • WiMinet 评说1.3:模拟式UDP中继技术缺陷
        在《WiMinet评说1.2:多跳无线网络的现状》一文中,我们提到:在室外长距离的无线自组织网络中,由于节点之间的链路损耗较大,其链路预算相对不足,其包误码率PER会相应升高,也就是丢包概率p会比较大;而在一个大规模网络中,某些分支节点的通讯链路又会比较深,也就是网络跳数n比......
  • 长链剖分&DP
    长链剖分优化DP长链剖分有一些美妙的性质一个点跳到根最多经过\(\sqrtn\)条链向上跳链,链长一定会增加,最坏是\(1,2,3,...,\sqrtn\)所有长链的总链长相加为n(如说)优化DP如果dp中有一维和深度有关,就考虑优化,考虑用长儿子\(O(1)\)转移(一般是平移,考虑用指针),其他暴力转......
  • 数论分块性质优化DP状态
    6311.mobitel给定一个r行s列的矩阵,每个格子里都有一个正整数。问如果从左上角走到右下角,且每次只能向右或向下走到相邻格子,那么使得路径上所有数的乘积不小于n的路径有多少条?对于100%的数据,1<=r,s<=300,1<=n<=10^6,矩阵中的数不超过10^6。so,一个普通的思想就是设f[......
  • 单调栈优化DP
    当有形如\(f_i=min_{j=0}^{l(i)}f_j+w转移代价\)我们就可以使用单调栈优化DP为什么不用单调队列???当有形如\(f_i=min_{j=l(i)}^{i-1}f_j+w转移代价\)我们就可以使用单调队列优化DP至于为毛,就可以从它的工作原理上去分析6305.最小值\(dp_i=min_{j=0}^{i-1}g_j+f(min_{x=j+1......
  • 动态DP
    动态DP最大子段和考虑设\(f_i\)表示以i为结尾的最大子段和,\(g_i\)表示i以内的最大子段和\[f_i=\max(f_{i-1}+a_i,a_i)\]\[g_i=\max(g_{i-1},f_i)\]然后非常容易将每个权值变成一个矩阵,然后每次修改就变成修改一个矩阵用线段树维护即可树上最大独立集(没有上司的舞会带修)考......
  • 基于STM32F407MAC与DP83848实现以太网通讯二(DP83848硬件配置以及寄存器)
    参考内容:DP83848数据表一、PHYDP83848功能模块图                     DP83848的硬件模块主要为:MII/RMII/SNI INTERFACES:用于与MAC数据传输的MII/RMII/SNI接口Transmit BLOCK:数据发送模块,将从外部MAC(例如STM32ETH外设的MAC)接收......
  • 基于STM32F407MAC与DP83848实现以太网通讯一(STM32以太网(ETH)外设)
    STM32F4xx可以通过以太网按照IEEE802.3-2002标准发送和接收数据。支持与外部物理层(PHY)相连的两个工业标准接口:默认情况下使用的介质独立接口(MII)(在IEEE802.3规范中定义)和简化介质独立接口(RMII)。具体的以太网(ETM)特性参考:STM32F4xx中文参考手册这里将重要的地方进......
  • 玉蟾宫(悬线dp)
    求最大子矩阵一般用采用悬线法(包好用的牢底)悬线法:[以这道题为例,我们将R称为障碍格子,将F称为非障碍格子]我们选择任意一个非障碍格子,引出三条直线:左直右直上直随后从这个点出发,分别向上左右延申直到遇到障碍格我们要求上悬线尽可能高的面积,但有可能上一......
  • linux常用命令--dpkg
    dpkg是Debain系列linux发行版本中的重要命令,用于管理软件包,安装、配置、卸载等等。更多介绍请参考官方文档:www.dpkg.orgdpkg常用参数:dpkg-ipackage_file.deb安装指定软件包 dpkg-igvim.debdpkg-rpackage_file.deb删除以安装的软件包,但保留配置文件 dpkg-rgv......