[APIO2015]巴厘岛的雕塑

题目描述

印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道。

在这条主干道上一共有 NN 座雕塑,为方便起见,我们把这些雕塑从 11 到 NN 连续地进行标号,其中第 ii 座雕塑的年龄是 Y_iYi 年。为了使这条路的环境更加优美,政府想把这些雕塑分成若干组,并通过在组与组之间种上一些树,来吸引更多的游客来巴厘岛。

下面是将雕塑分组的规则:

这些雕塑必须被分为恰好 XX 组,其中 A \leq X \leq BAXB ,每组必须含有至少一个雕塑,每个雕塑也必须属于且只属于一个组。同一组中的所有雕塑必须位于这条路的连续一段上。

当雕塑被分好组后,对于每个组,我们首先计算出该组所有雕塑的年龄和。

计算所有年龄和按位取或的结果。我们这个值把称为这一分组的最终优美度。

请问政府能得到的最小的最终优美度是多少?

备注:将两个非负数 PP 和 QQ 按位取或是这样进行计算的:

首先把 PP 和 QQ 转换成二进制。

设 n_PnP 是 PP 的二进制位数, n_QnQ 是 QQ 的二进制位数, MM 为 n_PnP 和 n_QnQ 中的最大值。 PP 的二进制表示为 p_{M-1}p_{M-2} \dots p_1p_0pM1pM2p1p0 , QQ 的二进制表示为 q_{M-1}q_{M-2} \dots q_1 q_0qM1qM2q1q0 ,其中 p_ipi 和 q_iqi 分别是 PP 和 QQ 二进制表示下的第 ii 位,第 M -1M1 位是数的最高位,第 00 位是数的最低位。

PP 与 QQ 按位取或后的结果是: (p_{M-1}\mathbin{\mathrm{OR}} q_{M-1})(p_{M-2}\mathbin{\mathrm{OR}}q_{M-2})\dots (p_1\mathbin{\mathrm{OR}} q_1) (p_0\mathbin{\mathrm{OR}}q_0)(pM1ORqM1)(pM2ORqM2)(p1ORq1)(p0ORq0) 。其中: 0 \mathbin{\mathrm{OR}} 0 = 00OR0=0

0 \mathbin{\mathrm{OR}} 1 = 10OR1=1

1 \mathbin{\mathrm{OR}} 0 = 11OR0=1

1 \mathbin{\mathrm{OR}} 1 = 11OR1=1

输入输出格式

输入格式:

 

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

第二行包含 NN 个用空格分开的整数 Y_1, Y_2, \dots, Y_NY1,Y2,,YN 。

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 复制
6 1 3
8 1 2 1 5 4
输出样例#1: 复制
11

说明

【样例解释】

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

【数据范围】

子任务 1 (9 分) 1 \leq N \leq 201N20

1 \leq A \leq B \leq N1ABN

0 \leq Y_i \leq 10000000000Yi1000000000

子任务 2 (16 分) 1 \leq N \leq 501N50

1 \leq A \leq B \leq \min\{20, N\}1ABmin{20,N}

0 \leq Y_i \leq 100Yi10

子任务 3 (21 分) 1 ≤ N ≤ 1001N100

A = 1A=1

1 \leq B \leq N1BN

0 \leq Y_i \leq 200Yi20

子任务 4 (25 分) 1 \leq N \leq 1001N100

1 \leq A \leq B \leq N1ABN

0 \leq Y_i \leq 10000000000Yi1000000000

子任务 5 (29 分) 1 \leq N \leq 20001N2000

A = 1A=1

1 \leq B \leq N1BN

0 \leq Y_i \leq 10000000000Yi1000000000

因为是最小优美度,所以贪心很显然,高位尽可能为0

n<=100时

首先从高到低枚举每一位

f[i][j]表示前i个,分了j组,这一位是否能为0

O(n^3)的DP

由于可能存在低位为0的方案与高位为0冲突

我们设一个变量now,第i位为1表示当前位必须为0

首先now该位变成1

转移条件(sum[i]-sum[j-1])&now=0

如果f[n][A~B]没有1,那么now该位改为0

当n<=1000时,因为A=1

换一种DP方式,f[i]表示前i位是否存在该位为0的方案,F[i]表示最小的分组数

看是否有F[n]<=B

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 int f[101][101],A,B,n,flag;
 9 lol pw[101],sum[2001],a[2001],now,ans,F[2001],Min[2001];
10 void dp1()
11 {int i,j,k,l;
12   int Log=log2(sum[n]);
13   pw[0]=1;
14   for (i=1;i<=Log;i++)
15     pw[i]=pw[i-1]*2;
16   for (i=Log;i>=0;i--)
17     {
18       now|=pw[i];
19       memset(f,0,sizeof(f));
20       f[0][0]=1;
21       for (j=1;j<=n;j++)
22       {
23         for (l=0;l<=j-1;l++)
24           if (((sum[j]-sum[l])&now)==0)
25             {
26             for (k=1;k<=l+1&&k<=j;k++)
27             f[j][k]|=f[l][k-1];
28             }
29       }
30       flag=0;
31       for (j=A;j<=B;j++)
32       {
33         if (f[n][j]) {flag=1;break;}
34       }
35       if (!flag)
36       now^=pw[i];
37     }
38   ans=0;
39   for (i=0;i<=Log;i++)
40     if ((now&pw[i])==0) ans+=pw[i];
41   cout<<ans;
42 }
43 void dp2()
44 {int i,j,k,l;
45   int Log=log2(sum[n]);
46   pw[0]=1;
47   for (i=1;i<=Log;i++)
48     pw[i]=pw[i-1]*2;
49   for (i=Log;i>=0;i--)
50     {
51       now|=pw[i];
52       memset(F,0,sizeof(F));
53       memset(Min,127/2,sizeof(Min));
54       F[0]=1;Min[0]=0;
55       for (j=1;j<=n;j++)
56       {
57         for (k=0;k<=j-1;k++)
58           if (((sum[j]-sum[k])&now)==0)
59           {
60             F[j]|=F[k];
61             if (F[k])
62             Min[j]=min(Min[j],Min[k]+1);
63           }
64       }
65       if (!(F[n]&&Min[n]<=B))
66       now^=pw[i];
67     }
68   ans=0;
69   for (i=0;i<=Log;i++)
70     if ((now&pw[i])==0) ans+=pw[i];
71   cout<<ans;
72 }
73 int main()
74 {int i;
75   cin>>n>>A>>B;
76   for (i=1;i<=n;i++)
77     {
78       scanf("%lld",&a[i]);
79       sum[i]=sum[i-1]+a[i];
80     }
81   if (n<=100)
82     dp1();
83   else
84     dp2();
85 }

 

posted @ 2018-04-22 19:19  Z-Y-Y-S  阅读(498)  评论(0编辑  收藏  举报