• 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
  • 相关阅读:
    netty内存泄漏
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    java 容器结构
    c3p0 一个数据库链接的例子
    eclipse java MemoryAnalyzer 查询内存泄漏 环境配置
    Java中数据库连接的一些方法资料汇总
    java io流
    MySQL的几个概念:主键,外键,索引,唯一索引
    mysql 一些常用指令
    mysql only_full_group_by问题
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8386235.html
Copyright © 2020-2023  润新知