魔术师的桌子上有n个杯子排成一行,编号为1,2,…,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。花费c_ij元,魔术师就会告诉你杯子i,i+1,…,j底下藏有球的总数的奇偶性。
采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?
标签:turn 分割 哪些 序列 long inpu closed 表示 ide
呃。。好像弃坑了好久=v=。。本来打算在bzoj每刷10题合起来写一份题解。。但是1个月好像还刷不到10题的样子(水题除外),所以还是单独写一下题解。。
魔术师的桌子上有n个杯子排成一行,编号为1,2,…,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。花费c_ij元,魔术师就会告诉你杯子i,i+1,…,j底下藏有球的总数的奇偶性。
采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?
第一行一个整数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个数。
输出一个整数,表示最少花费。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int fa[10001]; 4 struct dist{ 5 int u,v,dis; 6 }a[3000001]; 7 int find(int x){ 8 if(fa[x]!=x) fa[x]=find(fa[x]); 9 return fa[x]; 10 } 11 void u(int x,int y){ 12 if(find(x)!=find(y)) fa[find(x)]=find(y); 13 } 14 bool cmp(dist a,dist b){ 15 return a.dis<b.dis; 16 } 17 int main(){ 18 int n,m,k,p=0; 19 long long ans=0; 20 int c; 21 scanf("%d",&n); 22 m=(n+1)*n/2;//边数 23 for(int i=1;i<=n;i++){ 24 for (int j=i;j<=n;j++){ 25 scanf("%d",&c); 26 p++; 27 a[p].u=i; a[p].v=j+1; a[p].dis=c; 28 }//建边 29 } 30 sort(a+1,a+m+1,cmp); 31 n++; 32 for(int i=1;i<=n;i++) 33 fa[i]=i; 34 for(int i=1;i<=m;++i){ 35 if(find(a[i].u)!=find(a[i].v)){ 36 u(a[i].u,a[i].v); 37 k++; 38 ans+=a[i].dis; 39 } 40 if(k==n-1) break; 41 }//kruskal 42 printf("%lld\n",ans); 43 }
原谅我代码写的丑。。原谅我缩进写的丑。。毕竟模板是从pascal翻译过来的。。还学了一波多关键字快排。。
标签:turn 分割 哪些 序列 long inpu closed 表示 ide
原文地址:http://www.cnblogs.com/Watton/p/7067140.html