[PA2014]Kuglarz
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1335 Solved: 672
[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
1 2 3 4 5
4 3 2 1
3 4 5
2 1
5
Sample Output
7
HINT
需要猜出所有球的的奇偶性,必须知道互相关联的n-1
条信息。所以是不是想到了最小生成树。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<set> 9 #include<map> 10 #include<ext/pb_ds/priority_queue.hpp> 11 #define pa pair<int,int> 12 #define inf 1000000000 13 #define ll long long 14 using namespace std; 15 using namespace __gnu_pbds; 16 inline int read() 17 { 18 int x=0,f=1;char ch=getchar(); 19 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 20 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 21 return x*f; 22 } 23 int n; 24 ll ans; 25 int a[2005][2005],dis[2005]; 26 bool vis[2005]; 27 __gnu_pbds::priority_queue<pa,greater<pa> >::point_iterator id[2005]; 28 void prim() 29 { 30 __gnu_pbds::priority_queue<pa,greater<pa> >q; 31 for(int i=1;i<=n;i++)dis[i]=inf; 32 dis[0]=0; 33 id[0]=q.push(make_pair(0,0)); 34 while(!q.empty()) 35 { 36 int now=q.top().second;q.pop(); 37 ans+=dis[now];vis[now]=1; 38 for(int i=1;i<=n;i++) 39 if(a[now][i]<dis[i]&&!vis[i]) 40 { 41 dis[i]=a[now][i]; 42 if(id[i]==0)id[i]=q.push(make_pair(dis[i],i)); 43 else q.modify(id[i],make_pair(dis[i],i)); 44 } 45 } 46 } 47 int main() 48 { 49 n=read(); 50 for(int i=1;i<=n;i++) 51 for(int j=i;j<=n;j++) 52 a[i-1][j]=a[j][i-1]=read(); 53 prim(); 54 printf("%lld",ans); 55 }