首页 > 其他 > 详细

LA2238 Fixed Partition Memory Management

时间:2018-01-30 18:09:10      阅读:199      评论:0      收藏:0      [点我收藏+]

题目大意:

m(m<=10)个内存区域,n(n<=50)个程序。找出一个方案来,使得平均结束时刻尽量小。题目保证有解。

同一个程序运行在不同大小的内存区域内,其运行时间不同。(注意,这里说的大小是指整个内存区域大小,而不是说:该程序之前有程序运行,占用了一部分内存,剩下的那部分内存大小。。。。。。。)

 

输入:m和n,然后是m个数表示内存区域大小。再是n行,每行第1个数为情况总数k(k<=10),然后是k对整数s1,t1,s2,t2……sk,tk,满足si<si+1表示在各个内存中的运行时间。

如果内存块总大小s不足s1,则无法在该内存块运行该程序;当si<=s<si+1时,运行时间为ti;当s>=sk时,运行时间为tk

输出:平均最小结束时间和调度方案。

 (转自http://blog.csdn.net/u014679804/article/details/46725083)

 

题解:发现早运行的程序,对后面的结束时刻的影响是固定的,即某个内存区域倒数第p个,贡献为pT,T为程序在某个内存区域的运行时间。于是可以左边为程序,右边为每个内存区域倒数第几个运行,对应连边,边权为贡献,求最小权匹配。不难发现不会出现倒数第一匹配,倒数第二没匹配,倒数第三匹配的情况(何不匹配倒数第二呢?)

 

拍了很久,平均时间没有错,方案小数据看了很多组也没组

估计是SPJ没有或者不对。。。

网上的程序试了一个,都跟样例输出的一模一样,其他数据也都一模一样。。。

就当是对的吧。。OI一般也不会让输出方案反正。。

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #define max(a, b) ((a) > (b) ? (a) : (b))
 4 template<class T>
 5 inline void swap(T &a, T &b)
 6 {
 7     T tmp = a;a = b;b = tmp;
 8 }
 9 inline void read(int &x)
10 {
11     x = 0;char ch = getchar(), c = ch;
12     while(ch < 0 || ch > 9) c = ch, ch = getchar();
13     while(ch <= 9 && ch >= 0) x = x * 10 + ch - 0, ch = getchar();
14     if(c == -) x = -x;
15 }
16 const int INF = 0x3f3f3f3f;
17 const int MAXN = 200 + 5;
18 const int MAXM = 200 + 5;
19 int size[MAXM * MAXN], s[MAXM * MAXN], t[MAXM * MAXN], n, m, ca;
20 int g[MAXN][MAXN * MAXM], n1, n2, sla[MAXN * MAXM], pre[MAXN * MAXM], vis[MAXN * MAXM], lab1[MAXN * MAXN], lab2[MAXN * MAXM], lk1[MAXN * MAXN], lk2[MAXN * MAXM];
21 void cal(int x)
22 {
23     memset(vis, 0, sizeof(vis)), memset(sla, 0x3f, sizeof(sla)), memset(pre, 0, sizeof(pre)), vis[0] = 1;
24     int y;
25     do
26     {
27         y = 0;
28         for(int i = 1;i <= n2;++ i)
29         {
30             if(vis[i]) continue;
31             if(lab1[x] + lab2[i] - g[x][i] < sla[i]) sla[i] = lab1[x] + lab2[i] - g[x][i], pre[i] = x;
32             if(sla[i] < sla[y]) y = i;
33         }
34         int d = sla[y];
35         for(int i = 1;i <= n1;++ i) if(vis[lk1[i]]) lab1[i] -= d;
36         for(int i = 1;i <= n2;++ i) if(vis[i]) lab2[i] += d; else sla[i] -= d;
37         vis[y] = 1; 
38     }while(x = lk2[y]);
39     for(;y;swap(y, lk1[lk2[y] = pre[y]]));
40 }
41 double KM()
42 {
43     for(int i = 1;i <= n1;++ i) cal(i);
44     int ans = 0;
45     for(int i = 1;i <= n1;++ i) ans += g[i][lk1[i]];
46     return (double)-ans;
47 }
48 int tag[MAXN], from[MAXN], to[MAXN], stack[MAXN], tot;
49 int main()
50 {
51 
52     while(scanf("%d %d\n", &m, &n) != EOF && n && m)
53     {
54         if(ca) putchar(\n);
55         memset(from, 0, sizeof(from)), memset(tag, 0, sizeof(tag)), memset(to, 0, sizeof(to)), memset(stack, 0, sizeof(stack)), n1 = n, n2 = n * m, ++ ca, memset(lab1, -0x3f, sizeof(lab1)), memset(lk1, 0, sizeof(lk1)), memset(lk2, 0, sizeof(lk2)), memset(g, -0x3f, sizeof(g)), memset(lab2, 0, sizeof(lab2));
56         for(int i = 1;i <= m;++ i) read(size[i]);
57         for(int i = 1;i <= n;++ i)//考虑每个程序
58         {
59             int k;read(k);
60             for(int j = 1;j <= k;++ j) read(s[j]), read(t[j]);
61             s[k + 1] = INF;
62             for(int j = 1;j <= m;++ j)//在区域j中
63                 for(int l = 1;l <= k;++ l)
64                     if(s[l] <= size[j] && size[j] < s[l + 1])//运行时间为t[l]
65                         for(int p = 1;p <= n;++ p) //倒数第p个运行
66                             g[i][(j - 1) * n + p] = - p * t[l], lab1[i] = max(lab1[i], - p * t[l]); 
67         }
68         printf("Case %d\nAverage turnaround time = %.2lf\n", ca, KM() / (double)n);
69         for(int i = 1;i <= n;++ i) tag[i] = (lk1[i] - 1) / n + 1;
70         for(int i = 1;i <= m;++ i)
71         {
72             tot = 0;int sum = 0;
73             for(int j = 1;j <= n;++ j) if(tag[j] == i) stack[++ tot] = j;
74             for(;tot;-- tot) 
75                 from[stack[tot]] = sum, to[stack[tot]] = sum = sum + (-g[stack[tot]][lk1[stack[tot]]] / ((lk1[stack[tot]] - 1) % n + 1));
76         }
77         for(int i = 1;i <= n;++ i) printf("Program %d runs in region %d from %d to %d\n", i, tag[i], from[i], to[i]);
78     }
79     return 0;
80 }
LA2238

 

LA2238 Fixed Partition Memory Management

原文:https://www.cnblogs.com/huibixiaoxing/p/8386235.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!