【状态压缩DP】[APIO2007]动物园
2015-09-28 15:12
309 查看
2040: 【APIO2007】动物园
时间限制: 1 Sec 内存限制: 128 MB
提交: 22 解决: 8
[提交][状态][我的提交]
题目描述
新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,它包含一大圈围栏,每个围栏里有一种富有异国风情的动物。如下图所示:
你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高
兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好
的时光。但这并不是一件容易的事——有些小朋友喜欢某些动物,而有些小朋友
则害怕某些动物。例如,Alex 喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的
狮子。而 Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。
你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动
物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。
每个小朋友站在大围栏圈的外面,可以看到连续的 5 个围栏。你得到了所有
小朋友喜欢和害怕的动物信息。当出现下面两种情形之一时,小朋友就会高兴:
(1)至少有一个他害怕的动物(从视线可见的范围内)被移走,或
(2)至少有一个他喜欢的动物没有被(从视线可见的范围内)移走。
例如,考虑下图中的小朋友和动物:
假如你将围栏 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 是围栏数(10≤N≤10 000),
C 是小朋友的个数(1≤C≤50 000)。围栏按照顺时针的方向编号为 1,2,3,…,N。
接下来的 C 行,每行描述一个小朋友的信息,以下面的形式给出:
输出
仅输出一个数,表示最多可以让多少个小朋友高兴。
样例输入
Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
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
样例输出
5
提示
来源
[提交][状态][讨论版]
分析:
f[i][j]:i表示起始点,j表示动物的取舍状态。
num[i][j]表示以i开始j这种状态最多能令多少个站在j这个位置的小朋友满意。
f[i][j]=max(f[i][(j<<1)&31],f[i][(j<<1)&31+1]+num[i][j];
因为是环形,所以前4个应该固定,枚举前4个的取舍状态。
时间限制: 1 Sec 内存限制: 128 MB
提交: 22 解决: 8
[提交][状态][我的提交]
题目描述
新建的圆形动物园是亚太地区的骄傲。圆形动物园坐落于太平洋的一个小岛上,它包含一大圈围栏,每个围栏里有一种富有异国风情的动物。如下图所示:
你是动物园的公关主管。你要做的是,让每个参观动物园的游客都尽可能高
兴。今天有一群小朋友来到动物园参观,你希望能让他们在动物园度过一段美好
的时光。但这并不是一件容易的事——有些小朋友喜欢某些动物,而有些小朋友
则害怕某些动物。例如,Alex 喜欢可爱的猴子和考拉,而害怕拥有锋利牙齿的
狮子。而 Polly 会因狮子有美丽的鬃毛而喜欢它,但害怕有臭味的考拉。
你可以选择将一些动物从围栏中移走以使得小朋友不会害怕。但你移走的动
物也不能太多,否则留给小朋友们观赏的动物就所剩无几了。
每个小朋友站在大围栏圈的外面,可以看到连续的 5 个围栏。你得到了所有
小朋友喜欢和害怕的动物信息。当出现下面两种情形之一时,小朋友就会高兴:
(1)至少有一个他害怕的动物(从视线可见的范围内)被移走,或
(2)至少有一个他喜欢的动物没有被(从视线可见的范围内)移走。
例如,考虑下图中的小朋友和动物:
假如你将围栏 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 是围栏数(10≤N≤10 000),
C 是小朋友的个数(1≤C≤50 000)。围栏按照顺时针的方向编号为 1,2,3,…,N。
接下来的 C 行,每行描述一个小朋友的信息,以下面的形式给出:
输出
仅输出一个数,表示最多可以让多少个小朋友高兴。
样例输入
Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
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
样例输出
5
提示
来源
[提交][状态][讨论版]
分析:
f[i][j]:i表示起始点,j表示动物的取舍状态。
num[i][j]表示以i开始j这种状态最多能令多少个站在j这个位置的小朋友满意。
f[i][j]=max(f[i][(j<<1)&31],f[i][(j<<1)&31+1]+num[i][j];
因为是环形,所以前4个应该固定,枚举前4个的取舍状态。
[code]#include<cstdio> #include<algorithm> using namespace std; #define MAXC 10000 #define MAXE 5 void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; } } int n,c,x,y,e,f[MAXC+10][1<<MAXE],num[MAXC+10][1<<MAXE],ans; void dfs(int pos,int dep,int status) { if (dep>4) { if((y&status)||(x&status)!=x) num[e][status]++; return; } dfs(pos,dep+1,status); dfs(pos,dep+1,status|(1<<dep)); } void dp(int st){ int q,i,j,w1,w2,r; for(j=0;j<32;j++) f[0][j]=0; for(i=1;i<=n;i++) if(i<5) for(j=0;j<32;j++){ q=st>>(i-1); r=(1<<(5-i))-1; if((j&r)==q){ w1=(j<<1)&31,w2=w1+1; f[i][j]=max(f[i-1][w1],f[i-1][w2])+num[i][j]; } else f[i][j]=0; } else if(i+4<=n) for(j=0;j<32;j++){ w1=(j<<1)&31,w2=w1+1; f[i][j]=max(f[i-1][w1],f[i-1][w2])+num[i][j]; } else{ q=st&((1<<(i+4-n))-1); for(j=0;j<32;j++) if(j>>(n+1-i)==q){ w1=j<<1&31,w2=w1+1; f[i][j]=max(f[i-1][w1],f[i-1][w2])+num[i][j]; } else f[i][j]=0; } for(j=0;j<32;j++) ans=max(f [j],ans); } int main() { int i,j,t,cx,cy; Read(n),Read(c); for(i=1;i<=c;i++){ x=y=0; Read(e),Read(cx),Read(cy); for(j=1;j<=cx;j++) Read(t),x|=1<<((t+n-e)%n); for(j=1;j<=cy;j++) Read(t),y|=1<<((t+n-e)%n); dfs(i,0,0); } for(i=0;i<16;i++) dp(i); printf("%d",ans); }
相关文章推荐
- 常用ASCII码详细对照表
- NSString的内存管理问题
- 转载python2进制打包相关
- sublime text 3 3083 注册码
- iPhone被盗后续更新一:怎么找老机
- 企业的诚实正直
- 25-id to load is required for loading
- Unity事件机制应用
- U-Boot源代码下载地址
- JS写的一个日期选择控件(移动网页的),写得不当的地方,望各位大神指正
- poi解析xls和xlsx
- apache 无权限访问目录访问access forbin
- wget下载网络图片
- 1、Java安全之秘密密钥-对称加密
- 将OutLook.exe注册为服务,让其一直保持开启状态
- centos安装vmware workstation 找不到kernel header解决方法
- Redis 内存数据库
- 安卓:ViewPager图片轮播(法2)
- Js 实现图片放大功能
- mysql带参存储过程小例子