1. 程式人生 > >bzoj3714 [PA2014]Kuglarz

bzoj3714 [PA2014]Kuglarz

amp register code i+1 color char lar ace min

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

正解:最小生成樹。

與狡猾的商人類似,知道一個區間的奇偶性,實際上就是連了一條邊,如果這個圖連通,那麽所有的點就都知道奇偶性了。

於是我們把$[l,r+1]$連上對應邊權,做一遍最小生成樹即可,好像要用$prim$。

 1 #include <bits/stdc++.h>
 2 #define il inline
 3
#define RG register 4 #define ll long long 5 6 using namespace std; 7 8 int e[2010][2010],dis[2010],vis[2010],n; 9 ll ans; 10 11 il int gi(){ 12 RG int x=0,q=1; RG char ch=getchar(); 13 while ((ch<0 || ch>9) && ch!=-) ch=getchar(); 14 if (ch==-) q=-1,ch=getchar();
15 while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); 16 return q*x; 17 } 18 19 il void prim(){ 20 memset(dis,0x3f3f3f,sizeof(dis)),dis[1]=0; 21 for (RG int i=1,now,mn;i<=n;++i){ 22 now=0,mn=2147483640; 23 for (RG int j=1;j<=n;++j) 24 if (!vis[j] && mn>dis[j]) now=j,mn=dis[j]; 25 ans+=mn,vis[now]=1; 26 for (RG int j=1;j<=n;++j) 27 if (!vis[j] && e[now][j]) dis[j]=min(dis[j],e[now][j]); 28 } 29 return; 30 } 31 32 int main(){ 33 #ifndef ONLINE_JUDGE 34 freopen("Kuglarz.in","r",stdin); 35 freopen("Kuglarz.out","w",stdout); 36 #endif 37 n=gi(); 38 for (RG int i=1;i<=n;++i) 39 for (RG int j=i;j<=n;++j) e[i][j+1]=e[j+1][i]=gi(); 40 ++n,prim(),cout<<ans; return 0; 41 }

bzoj3714 [PA2014]Kuglarz