【BZOJ4069】[Apio2015]巴厘岛的雕塑

Description

印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道。
在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 1 到 N 连续地进行标号,其中第 i 座雕塑的年龄是 Yi 年。为了使这条路的环境更加优美,政府想把这些雕塑分成若干组,并通过在组与组之间种上一些树,来吸引更多的游客来巴厘岛。
下面是将雕塑分组的规则:
这些雕塑必须被分为恰好 X 组,其中 A< = X< = B,每组必须含有至少一个雕塑,每个雕塑也必须属于且只属于一个组。同一组中的所有雕塑必须位于这条路的连续一段上。
当雕塑被分好组后,对于每个组,我们首先计算出该组所有雕塑的年龄和。
计算所有年龄和按位取或的结果。我们这个值把称为这一分组的最终优美度。
请问政府能得到的最小的最终优美度是多少?
备注:将两个非负数 P 和 Q 按位取或是这样进行计算的:
首先把 P 和 Q 转换成二进制。
设 nP 是 P 的二进制位数,nQ 是 Q 的二进制位数,M 为 nP 和 nQ 中的最大值。P 的二进制表示为 pM−1pM−2…p1p0,Q 的二进制表示为 qM−1qM−2…q1q0,其中 pi 和 qi 分别是 P 和 Q 二进制表示下的第 i 位,第 M−1 位是数的最高位,第 0 位是数的最低位。
P 与 Q 按位取或后的结果是: (pM−1  OR  qM−1)(pM−2 OR qM−2)…(p1 OR q1)(p0 OR q0)。其中:
0 OR 0=0
0 OR 1=1
1 OR 0=1
1 OR 1=1

Input

输入的第一行包含三个用空格分开的整数 N,A,B。

第二行包含 N 个用空格分开的整数 Y1,Y2,…,YN。

Output

输出一行一个数,表示最小的最终优美度。

Sample Input

6 1 3
8 1 2 1 5 4

Sample Output

11
explanation
将这些雕塑分为 2 组,(8,1,2) 和 (1,5,4),它们的和是 (11) 和 (10),最终优美度是 (11 OR 10)=11。(不难验证,这也是最终优美度的最小值。)

HINT

子任务 1 (9 分)

1< = N< = 20
1< = A< = B< = N
0< = Yi< = 1000000000
子任务 2 (16 分)
1< = N< = 50
1< = A< = B< = min{20,N}
0< = Yi< = 10
子任务 3 (21 分)
1< = N< = 100
A=1
1< = B< = N
0< = Yi< = 20
子任务 4 (25 分)
1< = N< = 100
1< = A< = B< = N
0< = Yi< = 1000000000
子任务 5 (29 分)
1< = N< = 2000
A=1
1< = B< = N
0< = Yi< = 1000000000

题解:考虑按位贪心来做。从高到低枚举答案的每一位,对于当前位,我们先check一下当前位=0能否满足要求,如果可以,则当前位=0,否则=1。那么如何check呢?考虑DP,用f[i][j]表示前i个雕塑分成j组是否可行,如果要求当前位=0可以满足要求,那么就把所有可能使得当前位!=0的转移都打上删除标记即可。

但是这样的转移时O(n^3)的啊,于是看了题解。。。md你告诉我最后一个子任务A=1!!!那么直接将DP方程该为f[i]表示将前i个雕塑最少能分成几组,然后转移就是O(n^2)的了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
int n,A,B;
bool f[2][110],mp[2010][2010];
int g[2010];
ll ans,s[2010];
bool check(ll v)
{
if(v<=8)
{
v++,v--;
}
int i,j,k,d;
if(A==1)
{
memset(g,0x3f,sizeof(g)),g[0]=0;
for(i=1;i<=n;i++) for(j=0;j<i;j++)
if(!mp[i][j]&&!((s[i]-s[j])&v)) g[i]=min(g[i],g[j]+1);
return g[n]<=B;
}
memset(f[0],0,sizeof(f[0]));
f[0][0]=1;
for(i=1;i<=B;i++)
{
d=i&1;
memset(f[d],0,sizeof(f[d]));
for(j=1;j<=n;j++) for(k=0;k<j;k++) if(!mp[j][k]&&!((s[j]-s[k])&v)) f[d][j]|=f[d^1][k];
if(i>=A&&f[d][n]) return 1;
}
return 0;
} inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
scanf("%d%d%d",&n,&A,&B);
int i,j;
for(i=1;i<=n;i++) s[i]=rd()+s[i-1];
for(ll k=1ll<<40;k;k>>=1)
{
if(check(k))
{
for(i=1;i<=n;i++) for(j=0;j<i;j++) if((s[i]-s[j])&k) mp[i][j]=1;
}
else ans|=k;
}
printf("%lld",ans);
return 0;
}

【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP的更多相关文章

  1. [APIO2015]巴厘岛的雕塑[按位贪心+dp]

    题意 给你长度为 \(n\) 的序列,要求分成 \(k\) 段连续非空的区间,求所有区间和的 \(or\) 最小值. 分析 定义 \(f_{i,j}\) 表示前 \(i\) 个点分成 \(j\) 段的 ...

  2. bzoj千题计划239:bzoj4069: [Apio2015]巴厘岛的雕塑

    http://www.lydsy.com/JudgeOnline/problem.php?id=4069 a!=1: 从高位到低位一位一位的算 记录下哪些位必须为0 dp[i][j] 表示前i个数分为 ...

  3. [BZOJ4069][Apio2015]巴厘岛的雕塑

    题目大意 分成 \(x\) 堆,是的每堆的和的异或值最小 分析 这是一道非常简单的数位 \(DP\) 题 基于贪心思想,我们要尽量让最高位的 \(1\) 最小, 因此我们考虑从高位向低位进行枚举,看是 ...

  4. [APIO2015]巴厘岛的雕塑 --- 贪心 + 枚举

    [APIO2015]巴厘岛的雕塑  题目描述 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有\(N\)座雕塑,为方便起见,我们把这些雕塑从 1 到\(N\)连续地进行 ...

  5. bzoj 4069 [Apio2015]巴厘岛的雕塑 dp

    [Apio2015]巴厘岛的雕塑 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 494  Solved: 238[Submit][Status][Dis ...

  6. [APIO2015]巴厘岛的雕塑

    题目描述 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 NN 座雕塑,为方便起见,我们把这些雕塑从 11 到 NN 连续地进行标号,其中第 ii 座雕塑的年龄是 Y ...

  7. [APIO2015]巴厘岛的雕塑 贪心+DP+特殊数据优化

    写了好久.... 刚刚调了一个小时各种对拍,,,,最后发现是多写了一个等号,,,,内心拒绝 表示一开始看真的是各种懵逼啊 在偷听到某位大佬说的从高位开始贪心后发现可做 首先考虑小数据(因为可以乱搞) ...

  8. BZOJ 4069 [Apio2015]巴厘岛的雕塑 ——贪心

    自己首先想了一种方法$f(i)$表示前$i$个最小值为多少. 然而发现位运算并不满足局部最优性. 然后我们可以从高到低贪心的判断,使得每一组的和在一个特定的范围之内. 还要特判最后一个Subtask, ...

  9. 4069: [Apio2015]巴厘岛的雕塑

    Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 1 到 N 连续地进行标号,其中第 i 座雕塑的年龄 ...

随机推荐

  1. mysql优化30条建议

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  2. [转载]Linux 卸载JDK并安装新版本JDK (rpm,tar)

    FROM:http://josh-persistence.iteye.com/blog/1908549 一.查看Jdk的安装路径: whereis javawhich java (java执行路径)e ...

  3. python调用jieba(结巴)分词 加入自定义词典和去停用词功能

    把语料从数据库提取出来以后就要进行分词啦,我是在linux环境下做的,先把jieba安装好,然后找到内容是build jieba PKG-INFO setup.py test的那个文件夹(我这边是ji ...

  4. Node.js 内存泄露 定位

    之前我们在64位Linux服务器上使用Node.js时,当Node进程物理内存接近1.6G,由于谷歌V8引擎对内存的限制,会导致进程退出! 显然我们自身编码或npm加载的第3行模块存在内存泄露问题,那 ...

  5. python项目导出所需要的依赖库

    使用pip freeze $ pip freeze > requirements.txt 这种方式是把整个环境中的包都列出来了,如果是虚拟环境可以使用. 通常情况下我们只需要导出当前项目的req ...

  6. 【BIEE】06_UNION /UNION ALL集合中分类汇总求和占比字段特殊处理

    环境准备 基于[BIEE]04..中建立的事实表 通过UNION ALL后得到如下报表: 优秀员工薪水公式:CASE WHEN "EMP_FACT"."级别"= ...

  7. iOS将数组中的内容分拼接成字符串

    NSString *string = [array componentsJoinedByString:@","];--分隔符

  8. JavaScript单线程(setTimeout,setInterval)

    今天看到这篇文章,学到了不少东西 特此发出来 和大家分享 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执 ...

  9. Android下的ActionBar

    1 http://blog.csdn.net/lilu_leo/article/details/7674904 2 http://blog.csdn.net/eclipsexys/article/de ...

  10. 40: Redraiment的走法(不连续最长子字符串)

    题目描述 :   Redraiment是走梅花桩的高手.Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗? 样例输 ...