题意:
魔术师的桌子上有n个杯子排成一行,编号为1,2,…,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。花费c_ij元,魔术师就会告诉你杯子i,i+1,…,j底下藏有球的总数的奇偶性。
采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?
题解:
这种题想到就很水当然我想不到
转换为前缀和,
ci,j
c
i
,
j
相当于知道前缀i-前缀j的奇偶性。
那么就在j和i-1之间连一条费用为c_ij的边,然后跑最小生成树就好了。
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int fa[2010],n,len=0;
int findfa(int x) {return fa[x]==x?x:fa[x]=findfa(fa[x]);}
struct node{
int x,y,c;
}e[2010*2010];
bool cmp(node a,node b) {return a.c<b.c;}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=i;j<=n;j++)
{
int x;
scanf("%d",&x);
e[++len].x=i;e[len].y=j+1;e[len].c=x;
}
for (int i=1;i<=n+1;i++) fa[i]=i;
sort(e+1,e+len+1,cmp);
LL ans=0;
for (int i=1;i<=len;i++)
{
int x=findfa(e[i].x),y=findfa(e[i].y);
if (x!=y) fa[x]=y,ans+=e[i].c;
}
printf("%lld",ans);
return 0;
}