Gym - 100548C The Problem Needs 3D Arrays
Problem C. The Problem Needs 3D Arrays
Time Limit: 6000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u
Description
A permutation is a sequence of integers p1,p2,...,pn, consisting of n distinct positive integers and each of them does not exceed n. Assume that r(S) of sequence S denotes the number of inversions in sequence S (if i < j and Si > Sj, then the pair of (i,j) is called an inversion of S), l(S) of sequence S denotes the length of sequence S. Given a permutation P of length n, it’s your task to find a subsequence S of P with maximum. A subsequence of P is a sequence (pi1,pi2,...,pit) which satisfies that 0 < i1 < i2 < ... < it ≤ n.
Input
The first line of the input gives the number of test cases, T. T test cases follow.
For each test case, the first line contains an integer n (1 ≤ n ≤ 100), the length of the permutation P. The second line contains n integers p1,p2,...,pn, which represents the permutation P.
Output
For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the maximum.
Your answer will be considered correct if it is within an absolute error of 10−6 of the correct answer.
Samples
Sample Input |
Sample Output |
1 5 3 4 2 5 1 |
Case #1: 1.250000000000 |
解题:最大密度子图转为最大权闭合图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 12000; 4 const int INF = 0x3f3f3f3f; 5 int n,m,tot,S,T,x[maxn],y[maxn],A[102]; 6 struct arc { 7 int to,next; 8 double flow; 9 arc(int x = 0,double y = 0,int z = -1) { 10 to = x; 11 flow = y; 12 next = z; 13 } 14 } e[maxn<<4]; 15 int head[maxn],cur[maxn],d[maxn]; 16 void add(int u,int v,double flow) { 17 e[tot] = arc(v,flow,head[u]); 18 head[u] = tot++; 19 e[tot] = arc(u,0,head[v]); 20 head[v] = tot++; 21 } 22 queue<int>q; 23 bool bfs() { 24 memset(d,-1,sizeof d); 25 while(!q.empty()) q.pop(); 26 q.push(S); 27 d[S] = 1; 28 while(!q.empty()) { 29 int u = q.front(); 30 q.pop(); 31 for(int i = head[u]; ~i; i = e[i].next) { 32 if(e[i].flow > 0 && d[e[i].to] == -1) { 33 d[e[i].to] = d[u] + 1; 34 q.push(e[i].to); 35 } 36 } 37 } 38 return d[T] > -1; 39 } 40 double dfs(int u,double low) { 41 if(u == T) return low; 42 double tmp = 0,a; 43 for(int &i = cur[u]; ~i; i = e[i].next) { 44 if(e[i].flow > 0 && d[e[i].to] == d[u] + 1 &&(a=dfs(e[i].to,min(e[i].flow,low)))>0) { 45 e[i].flow -= a; 46 e[i^1].flow += a; 47 low -= a; 48 tmp += a; 49 if(low <= 0) break; 50 } 51 } 52 if(tmp <= 0) d[u] = -1; 53 return tmp; 54 } 55 bool dinic() { 56 double ans = m; 57 while(bfs()) { 58 memcpy(cur,head,sizeof head); 59 ans -= dfs(S,INF); 60 } 61 return ans <= 0; 62 } 63 void build(double delta) { 64 memset(head,-1,sizeof head); 65 for(int i = tot = 0; i < m; ++i) { 66 add(S,i + n + 1,1.0); 67 add(i + n + 1,x[i],INF); 68 add(i + n + 1,y[i],INF); 69 } 70 for(int i = 1; i <= n; ++i) add(i,T,delta); 71 } 72 int main() { 73 int cm = 1,cs; 74 scanf("%d",&cs); 75 while(cs--) { 76 scanf("%d",&n); 77 m = 0; 78 for(int i = 1; i <= n; ++i) { 79 scanf("%d",A+i); 80 for(int j = i-1; j > 0; --j) 81 if(A[j] > A[i]) { 82 x[m] = j; 83 y[m++] = i; 84 } 85 } 86 S = 0; 87 T = n + m + 1; 88 double low = 0,high = m,ans = 0; 89 if(m == 0) {printf("Case #%d: %.7f\n",cm++,ans);continue;} 90 while(high - low > 1e-7){ 91 double mid = (low + high)/2.0; 92 build(mid); 93 if(dinic()) ans = high = mid; 94 else low = mid; 95 } 96 printf("Case #%d: %.7f\n",cm++,ans); 97 } 98 return 0; 99 }