巴厘岛的雕塑

Time Limit: 10 Sec  Memory Limit: 64 MB
[Submit][Status][Discuss]

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

Main idea

  将一个序列分为若干组,使得每组的和OR起来的值最小。

Solution

  根据题意,要使最终的答案最小,可以想到利用贪心,从高到低枚举答案的每一位,如果能取0则取0,否则取1。

  问题转化为如何判断答案的某一位能否取0,我们考虑用DP解决这个问题。假设当前枚举到第pos位。

  令f[i][j]表示前i个数分成j组,显然该位可以填0的条件是:

  1.存在k在i前面分了j-1组可行;

  2.异或值满足之前已经枚举的相同(保证最小)

  3.这一位可以是0

  这样可以过71分,最后一组数据TLE,发现最后一组数据下界固定为1,由于显然发现组数越小越优,可以令g[i]表示令第i位为0的最小组数,如果组数<B则这位可以为0。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE=; int n,A,B;
int a[ONE],g[ONE];
bool f[ONE][ONE];
long long Sum[ONE];
long long res;
long long total;
int PD,len; int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void PartOne()
{
for(int pos=len;pos>=;pos--)
{
memset(f,,sizeof(f));
f[][]=; for(int i=;i<=n;i++)
for(int j=;j<=i;j++)
for(int k=;k<=i-;k++)
{
total=Sum[i]-Sum[k]; if(f[k][j-] && ((total>>pos)|res)==res && ((total>>(pos-)) & (long long))== )
{
f[i][j]=;
break;
}
} PD=;
for(int i=A;i<=B;i++)
{
PD=f[n][i];
if(PD) break;
}
res<<=;
if(!PD) res|=;
}
} void PartTwo()
{
for(int pos=len;pos>=;pos--)
{
memset(g,,sizeof(g));
g[]=;
for(int i=;i<=n;i++)
for(int k=;k<=i-;k++)
{
total=Sum[i]-Sum[k]; if(((total>>pos)|res)==res && ((total>>(pos-)) & (long long))== )
{
g[i]=min(g[i],g[k]+);
}
} res<<=;
if(g[n]>B) res|=;
} } int main()
{
n=get(); A=get(); B=get();
for(int i=;i<=n;i++)
{
a[i]=get();
Sum[i]=Sum[i-]+a[i];
} total=Sum[n];
while(total)
{
len++;
total>>=;
} if(A!=) PartOne();
else PartTwo(); printf("%lld",res); }

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

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

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

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

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

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

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

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

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

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

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

  6. APIO2015巴厘岛的雕塑——数位DP

    题目:https://www.luogu.org/problemnew/show/P3646 对于A>1,将答案各位全置1,然后从高位到低位改成0判断是否可行: 用f[i][j]数组代表前i个数 ...

  7. bzoj 4069: [Apio2015]巴厘岛的雕塑【dp】

    居然要对不同的数据写不同的dp= = 首先记得开long long,<<的时候要写成1ll<<bt 根据or的性质,总体思路是从大到小枚举答案的每一位,看是否能为0. 首先对于 ...

  8. 【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP

    [BZOJ4069][Apio2015]巴厘岛的雕塑 Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 ...

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

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

随机推荐

  1. C语言 命令行参数 函数指针 gdb调试

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21551397 | http://www.hanshul ...

  2. 哈希表 STL map

    计数排序时我们使用一个数组来记录出现的数字的次数,而当数据范围太大时,无法建立一个那么大地数组(而且可能空间利用率很低,太浪费),此时可以改用hash table . binary search tr ...

  3. lintcode-163-不同的二叉查找树

    163-不同的二叉查找树 给出 n,问由 1...n 为节点组成的不同的二叉查找树有多少种? 样例 给出n = 3,有5种不同形态的二叉查找树: 标签 卡特兰数 动态规划 思路 参考博客http:// ...

  4. linux的几个发行网站

     Red Hat: http://www.redhat.com  Fedora: http://fedoraproject.org/  Mandriva: http://www.mandriva ...

  5. java 字符串—数字常用处理

    // 判断一个字符串是否都为数字 public boolean isDigit(String strNum) { return strNum.matches("[0-9]{1,}" ...

  6. P1365 WJMZBMR打osu! / Easy

    题目背景 原 维护队列 参见P1903 题目描述 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有 nnn 次点击要做,成功了就是o,失败了 ...

  7. 楼房 洛谷1382 && codevs2995

    P1382 楼房 题目描述 地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i]).地平 ...

  8. Shell编程语法

    创建shell程序的步骤: 第一步:创建一个脚本文件.sh. 第二步:授予权限使它可以执行chmod u+x .sh 第三步:执行 ./example 或者 sh example 脚本调试:      ...

  9. c#中文件流的读写

    文件流读入:第一static void Main(string[] args) { //C#文件流写文件,默认追加FileMode.Append string msg = "okffffff ...

  10. React ref的用法

    React的ref有3种用法: 1. 字符串(已废弃)2. 回调函数3. React.createRef() (React16.3提供) 1. 字符串 最早的ref用法. 1.dom节点上使用,通过t ...