题目链接:hihocoder 第64周
题意概述: 上下文菜单是panel(面板)包括很多section(分区),一个分区里面至少包含一个菜单项.每一个菜单项都对应有一个子panel,这个panel可能为空.也可能又是一个新的包含很多分区的panel.如何安排同一个section内的菜单项顺序?如何安排同一个panel内的各个分区?才能使的展开之后最短,占的空间最少?
方法:子级菜单长度-我的菜单长度=h,对h进行排序.h大的在上面.
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<stdio.h> 5 #include<string.h> 6 #include<string> 7 using namespace std; 8 #define ll long long 9 #define re(i,n) for(int i=0;i<n;i++) 10 const int maxn = 1007; 11 int n; 12 /* 13 Sec类是一个分区,分区包含很多菜单项; 14 每个菜单项是一个Panel. 15 a.size()表示这个分区所包含的菜单个数 16 h表示子菜单比本体长多少 17 */ 18 struct Sec{ 19 vector<int>a; 20 int h; 21 }; 22 /* 23 这个vector表示全部的panel.一个菜单项必然对应一个panel. 24 h表示子菜单比本体长多少 25 cnt表示此panel所包含的菜单项数 26 */ 27 vector<Sec>a[maxn]; 28 int h[maxn],cnt[maxn]; 29 bool cmp(const Sec&m, const Sec&n){ 30 return m.h > n.h; 31 } 32 bool cm(const int&m, const int &n){ 33 return h[m] > h[n]; 34 } 35 void go(int); 36 void go(Sec&sec){ 37 re(i, sec.a.size())go(sec.a[i]); 38 sort(sec.a.begin(), sec.a.end(), cm); 39 sec.h = 0; 40 int sz = sec.a.size(); 41 re(i, sz)sec.h = max(i + h[sec.a[i]] - sz, sec.h); 42 } 43 void go(int r){ 44 re(i, a[r].size())go(a[r][i]); 45 sort(a[r].begin(), a[r].end(), cmp); 46 int now = 0; 47 h[r] = cnt[r]; 48 int sz = a[r].size(); 49 re(i, sz){ 50 int self = a[r][i].a.size();//第i个sec的包含的菜单数 51 now += self; 52 h[r] = max(now +a[r][i].h, h[r]); 53 } 54 } 55 int main(){ 56 freopen("in.txt", "r", stdin); 57 cin >> n; 58 re(i, n + 1){ 59 scanf("%d", &cnt[i]); 60 Sec sec; 61 re(j, cnt[i]){ 62 int x; scanf("%d", &x); 63 if (x == 0){ 64 j--; 65 a[i].push_back(sec); 66 sec.a.clear(); 67 continue; 68 } 69 sec.a.push_back(x); 70 } 71 a[i].push_back(sec); 72 } 73 go(0); 74 printf("%d ", h[0]); 75 return 0; 76 }