zoukankan      html  css  js  c++  java
  • bzoj3714 [PA2014]Kuglarz

    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

    把杯子根据有没有球看成0/1的序列,题意是可以询问一段区间的和,要求确定每一个点的状态数

    显然要一直取到长度为1的区间,才能确定这个点。

    考虑把原来的序列划分成一些连续的区间,只要求出每一段的最小代价加上这样划分的代价就好了

    这样变成不停的在序列上划分。显然每次划分都使得区间数+1,最终必须划分成n个长度为1的区间,因为要知道每一个点的状态

    这样一来只需要考虑划分成n-1个区间的最小代价就好了

    但是实际上划分的顺序对答案是不影响的,而且显然划分成n-1个区间就相当于连n-1条线

    所以变成最小生成树了……真神奇

    另外……因为a[i][j]实际上是把区间[i-1,j]提出来的代价,所以应该求0到n一共n+1个点的最小生成树

    听说prim加个堆优化能跑得飞快,但是还没打,就写了个很sb的n^2prim

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<deque>
     9 #include<set>
    10 #include<map>
    11 #include<ctime>
    12 #define LL long long
    13 #define inf 2147483647
    14 #define pa pair<int,int>
    15 #define pi 3.1415926535897932384626433832795028841971
    16 #define N 2010
    17 using namespace std;
    18 int a[N][N];
    19 int near[N];
    20 bool mrk[N];
    21 int n;
    22 LL ans;
    23 inline LL read()
    24 {
    25     LL x=0,f=1;char ch=getchar();
    26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 inline void prim()
    31 {
    32     mrk[0]=1;
    33     for(int i=1;i<=n;i++)
    34       near[i]=a[0][i];
    35     for (int i=1;i<=n;i++)
    36     {
    37         int mn=inf,fnd=0;
    38         for (int j=1;j<=n;j++)
    39           if (!mrk[j]&&near[j]<mn)
    40           {
    41             mn=near[j];
    42             fnd=j;
    43           }
    44         ans+=mn;
    45         mrk[fnd]=1;
    46         for (int j=1;j<=n;j++)
    47           if (!mrk[j]) near[j]=min(near[j],a[fnd][j]);
    48     }
    49 }
    50 int main()
    51 {
    52     n=read();
    53     for (int i=1;i<=n;i++)
    54     for (int j=i;j<=n;j++)
    55       a[i-1][j]=a[j][i-1]=read();
    56     prim();
    57     printf("%lld
    ",ans);
    58 }
    bzoj3714
    ——by zhber,转载请注明来源
  • 相关阅读:
    Sqlite框架Delphi10.3(07)
    FastReport 6.8.11在Delphi10.3上的安装
    Delphi 中,InputQuery 函数的妙用
    Javaday25(sax解析xml,json,设计模式)
    并发学习第五篇——volatile关键字
    并发学习第四篇——synchronized关键字
    并发学习第二篇——Thread
    并发学习第一篇——Runnable
    git-仓库迁移并保留commit log
    并发编程理论基础二——画图理解
  • 原文地址:https://www.cnblogs.com/zhber/p/4055158.html
Copyright © 2011-2022 走看看