zoukankan      html  css  js  c++  java
  • uoj #110. 【APIO2015】Bali Sculptures

    #110. 【APIO2015】Bali Sculptures

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

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

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

    • 这些雕塑必须被分为恰好 XX 组,其中 AXBA≤X≤B,每组必须含有至少一个雕塑,每个雕塑也必须属于且只属于一个组。同一组中的所有雕塑必须位于这条路的连续一段上。
    • 当雕塑被分好组后,对于每个组,我们首先计算出该组所有雕塑的年龄和。
    • 计算所有年龄和按位取或的结果。我们这个值把称为这一分组的最终优美度。

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

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

    • 首先把 PP 和 QQ 转换成二进制。
    • 设 nPnP 是 PP 的二进制位数,nQnQ 是 QQ 的二进制位数,MM 为 nPnP 和 nQnQ 中的最大值。PP 的二进制表示为 pM1pM2p1p0pM−1pM−2…p1p0,QQ 的二进制表示为 qM1qM2q1q0qM−1qM−2…q1q0,其中 pipi 和 qiqi 分别是 PP 和 QQ 二进制表示下的第 ii 位,第 M1M−1 位是数的最高位,第 00 位是数的最低位。
    • PP 与 QQ 按位取或后的结果是: (pM1ORqM1)(pM2ORqM2)(p1ORq1)(p0ORq0)(pM−1ORqM−1)(pM−2ORqM−2)…(p1ORq1)(p0ORq0)。其中:
      • 0OR0=00OR0=0
      • 0OR1=10OR1=1
      • 1OR0=11OR0=1
      • 1OR1=11OR1=1

    输入格式

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

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

    输出格式

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

    样例一

    input

    6 1 3
    8 1 2 1 5 4
    
    

    output

    11
    
    

    explanation

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

    子任务

    • 子任务 1 (9 分)
      • 1N201≤N≤20
      • 1ABN1≤A≤B≤N
      • 0Yi10000000000≤Yi≤1000000000
    • 子任务 2 (16 分)
      • 1N501≤N≤50
      • 1ABmin{20,N}1≤A≤B≤min{20,N}
      • 0Yi100≤Yi≤10
    • 子任务 3 (21 分)
      • 1N1001≤N≤100
      • A=1A=1
      • 1BN1≤B≤N
      • 0Yi200≤Yi≤20
    • 子任务 4 (25 分)
      • 1N1001≤N≤100
      • 1ABN1≤A≤B≤N
      • 0Yi10000000000≤Yi≤1000000000
    • 子任务 5 (29 分)
      • 1N20001≤N≤2000
      • A=1A=1
      • 1BN1≤B≤N
      • 0Yi10000000000≤Yi≤1000000000

    时间限制1s1s

    空间限制64MB

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 110
    using namespace std;
    int n,A,B,w[maxn],cnt;
    long long b[maxn],ans=1000000000000000LL;
    long long check(int sta){
        long long res=0;
        cnt=1;
        b[1]=0;
        for(int i=1;i<n;i++){
            b[cnt]+=w[i];
            if(sta&(1<<(i-1))){
                res|=b[cnt];
                cnt++;
                b[cnt]=0;
            }
            if(cnt>B)return -1;
        }
        if(cnt<A)return -1;
        b[cnt]+=w[n];
        res|=b[cnt];
        return res;
    }
    int main(){
        scanf("%d%d%d",&n,&A,&B);
        for(int i=1;i<=n;i++)scanf("%d",&w[i]);
        for(int i=0;i<(1<<(n-1));i++){
            long long now=check(i);
            if(now!=-1)
                ans=min(ans,now);
        }
        cout<<ans<<endl;
    }
    9分 暴力
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define INF 0x3f3f3f3f
    #define maxn 2010
    using namespace std;
    int f[105][105],g[maxn],n,A,B;
    long long a[maxn],sum[maxn],ans;
    void solve1(){
        for(int pos=45;pos>=0;pos--){
            memset(f,1,sizeof(f));
            f[0][0]=0;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=B;j++)
            for(int k=0;k<i;k++)
                if(f[k][j-1]==0 && (((sum[i]-sum[k])>>pos)&1)==0 && (((sum[i]-sum[k])|ans)>>pos)==(ans>>pos)){
                    f[i][j]=0;
                    break;
                }
            bool flag=0;
            for(int i=A;i<=B;i++)
                if(f[n][i]==0){flag=1;break;}
            if(!flag)ans|=1LL<<pos;
        }
        cout<<ans<<endl;
    }
    void solve2(){
        for(int pos=51;pos>=0;pos--){
            for(int i=1;i<=n;i++)g[i]=INF;
            g[0]=0;
            for(int i=1;i<=n;i++)
                for(int j=0;j<i;j++){
                    if((((sum[i]-sum[j])>>pos)&1))continue;
                    if((((sum[i]-sum[j])|ans)>>pos)==(ans>>pos))
                        g[i]=min(g[i],g[j]+1);
                }
            if(g[n]>B)ans|=1LL<<pos;
        }
        cout<<ans<<endl;
    }
    int main(){
        scanf("%d%d%d",&n,&A,&B);
        for(int i=1;i<=n;i++){
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        if(A==1)solve2();
        else solve1();
        return 0;
    }
    100分 动态规划
  • 相关阅读:
    在springmvc中,什么是逻辑视图?什么是物理视图?
    docker2
    docker1
    HTTP Service 中篇
    HTTP Service 上篇
    Centos7 fstab盘符挂载硬盘导致重启系统失败解决办法
    vsphere网络
    LVS的工作原理认识
    数字转换
    对def函数的参数认识
  • 原文地址:https://www.cnblogs.com/thmyl/p/8976446.html
Copyright © 2011-2022 走看看