zoukankan      html  css  js  c++  java
  • bzoj 3714: [PA2014]Kuglarz

    3714: [PA2014]Kuglarz

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1151  Solved: 611
    [Submit][Status][Discuss]

    Description

    魔术师的桌子上有n个杯子排成一行,编号为1,2,…,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。花费c_ij元,魔术师就会告诉你杯子i,i+1,…,j底下藏有球的总数的奇偶性。
    采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?

    Input

    第一行一个整数n(1<=n<=2000)。
    第i+1行(1<=i<=n)有n+1-i个整数,表示每一种询问所需的花费。其中c_ij(对区间[i,j]进行询问的费用,1<=i<=j<=n,1<=c_ij<=10^9)为第i+1行第j+1-i个数。

    Output

    输出一个整数,表示最少花费。

    Sample Input

    5
    1 2 3 4 5
    4 3 2 1
    3 4 5
    2 1
    5

    Sample Output

    7

    HINT

     

    Source

     
    我们可以发现,当我们知道了[a,b]和[b+1,c]之后,就可以知道[a,c];
    同样的,当我们知道了[a,c]和[b,c]之后也就可以知道了[a,b-1]。
     
    或者换一个更加显然的说法,设空间i为i物品左边的空当,空间n+1为n右边的空当。
    我们查询一次[l,r]就相当于知道了空当[l,r+1]直接的物品的奇偶性。
    当我们知道了空当[a,b]和[b,c]之后就可以知道[a,c];
    当我们知道了空当[a,c]和[b,c]之后就可以知道[a,b]。
     
    所以一次操作[l,r]就相当于吧l于r+1所在的等价类集合合并。。。
    然后就发现这个的本质是一道最小生成树。。。
     
    /**************************************************************
        Problem: 3714
        User: JYYHH
        Language: C++
        Result: Accepted
        Time:9172 ms
        Memory:24796 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 2005
    using namespace std;
    struct lines{
        int u,v,w;
        bool operator <(const lines &u)const{
            return w<u.w;
        }
    }l[maxn*1000];
    ll ans=0;
    int n,m,cnt=0;
    int now,p[maxn];
     
    int ff(int x){
        return p[x]==x?x:(p[x]=ff(p[x]));
    }
     
    int main(){
        scanf("%d",&n);
        n++;
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++){
                scanf("%d",&now);
                l[++cnt]=(lines){i,j,now};
            }
         
        for(int i=1;i<=n;i++) p[i]=i;
         
        int fa,fb,tot=0;
        sort(l+1,l+cnt+1);
        for(int i=1;i<=cnt;i++){
            fa=ff(l[i].u),fb=ff(l[i].v);
            if(fa!=fb){
                ans+=(ll)l[i].w;
                p[fa]=fb;
                if((++tot)==n-1) break;
            }
        }
         
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    spring属性的三种注入方法
    spring整合web项目原理
    IOC与DI区别
    近期的一些思考(前后台对接方面)
    关于form表单回车自动刷新
    css画心形、三角形的总结
    网页播放器与播放器定制
    css实现div内凹角样式
    20190614笔记(颜色透明度,css,filter,滤镜,计算属性,json和formData转换)
    关于注册页面的总结
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8502690.html
Copyright © 2011-2022 走看看