zoukankan      html  css  js  c++  java
  • LA2238 Fixed Partition Memory Management

    题目大意:

    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
    ", &m, &n) != EOF && n && m)
    53     {
    54         if(ca) putchar('
    ');
    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
    Average turnaround time = %.2lf
    ", 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
    ", i, tag[i], from[i], to[i]);
    78     }
    79     return 0;
    80 }
    LA2238
  • 相关阅读:
    WCF 第十三章 可编程站点 为站点创建操作
    WCF 第十三章 可编程站点 所有都与URI相关
    WCF 第十二章 对等网 使用自定义绑定实现消息定向
    WCF 第十三章 可编程站点 使用WebOperationContext
    Using App.Config for user defined runtime parameters
    WCF 第十三章 可编程站点
    WCF 第十三章 可编程站点 使用AJAX和JSON进行网页编程
    WCF 第十二章 总结
    WCF 第十三章 可编程站点 使用WebGet和WebInvoke
    WCF 第十三章 可编程站点 URI和UriTemplates
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8386235.html
Copyright © 2011-2022 走看看