zoukankan      html  css  js  c++  java
  • [CmdOI2019]任务分配问题

    题目描述

    在某台有kk个CPU的计算机中,有nn个计算任务等待执行。

    a_iai​为第ii个任务的优先级,方便起见,aa为一个排列。

    现在,要将这些任务分配给CPU去解决。

    由于内存等原因,一个CPU只能负责连续一段的任务,并且要按(从左到右的)顺序执行。

    在某个CPU内,无序度定义为 : 前者先执行,而后者优先级高的任务对的个数。

    请最小化每个CPU的无序度之和。

    输入格式

    第一行两个整数n,kn,k,分别表示任务个数和CPU个数。

    第二行nn个整数,表示a_{1...n}a1...n​

    输出格式

    输出一个整数,表示最小的无序度之和。

    输入输出样例

    输入 #1复制
    5 1
    1 5 4 2 3
    输出 #1复制
    5
    输入 #2复制
    5 2
    1 5 4 2 3
    输出 #2复制
    1
    输入 #3复制
    8 3
    1 3 5 2 7 4 8 6
    输出 #3复制
    4
    说明/提示

    测试点编号 n k
    1~2 25000 1
    3 25000 2
    4~5 1000 10
    6~10 25000 25
    (保证kleq nk≤n , #6~10时限2S)

    样例解释:

    样例1
    此时只能把所有任务交给单独的一个CPU。

    第一个任务和其他所有任务都形成无序任务对。

    此外最后两个任务也形成无序任务对,共5个。

    样例2
    第一个CPU单独处理任务1,无序度为0;

    第二个CPU处理{5,4,2,3}{5,4,2,3}无序度为1;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int c[50005],tr,tl,f[30][25005],a[25005],s,n,k;
     7 void del(int x)
     8 {
     9     while (x<=n)
    10     {
    11         c[x]-=1;
    12         x+=(x&(-x));
    13     }
    14 }
    15 void add(int x)
    16 {
    17     while (x<=n)
    18     {
    19         c[x]+=1;
    20         x+=(x&(-x));
    21     }
    22 }
    23 int query(int x)
    24 {
    25     int sum=0;
    26     while (x)
    27     {
    28         sum+=c[x];
    29         x-=(x&(-x));
    30     }
    31     return sum;
    32 }
    33 int get(int l,int r)
    34 {
    35     while (tl<l) 
    36     {
    37         del(a[tl]);
    38         s-=tr-tl-query(a[tl]);
    39         tl++;
    40     }
    41     while (tl>l)
    42     {
    43         tl--;
    44         s+=tr-tl-query(a[tl]);
    45         add(a[tl]);
    46     }
    47     while (tr<r)
    48     {
    49         tr++;
    50         s+=query(a[tr]);
    51         add(a[tr]);
    52     }
    53     while (tr>r)
    54     {    
    55         del(a[tr]);
    56         s-=query(a[tr]);
    57         tr--;
    58     } 
    59     return s;
    60 }
    61 void solve(int x,int l,int r,int L,int R)
    62 {int i,Mid;
    63     if (l>r) return;
    64     int mid=(l+r)/2;
    65     Mid=mid;
    66     for (i=L;i<=min(mid-1,R);i++)
    67     {
    68         int t=f[x-1][i]+get(i+1,mid);
    69         if (f[x][mid]>=t) 
    70         {
    71             f[x][mid]=t;
    72             Mid=i;
    73         }
    74     }
    75     solve(x,l,mid-1,L,Mid);
    76     solve(x,mid+1,r,Mid,R);
    77 }
    78 int main()
    79 {int i,j;
    80     scanf("%d%d",&n,&k);
    81     for (i=1;i<=n;i++)
    82     scanf("%d",&a[i]);
    83     memset(f,127/2,sizeof(f));
    84     tl=1;tr=0;
    85     for (i=1;i<=n;i++)
    86     {
    87         f[1][i]=get(1,i);
    88     } 
    89     for (i=2;i<=k;i++)
    90     {
    91         solve(i,i,n,i-1,n);
    92     }
    93     printf("%d",f[k][n]);
    94 }
  • 相关阅读:
    cocos2dx触摸响应
    MFC注册热键
    隐式类型转换
    virtualbox导入winXP系统OVA文件重启
    virtualbox虚拟机下的cdlinux找不到无线网卡的解决方法
    批处理,修改环境变量path的方法(加环境变量)
    什么是堆和栈,它们在哪儿?
    ON_WM_TIMER() void (__cdecl xx::* )(UINT)”转换为“void (__cdecl CWnd::* )(UINT_PTR)
    读书笔记:《你的知识需要管理》
    linux系统管理-软件包管理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/12245994.html
Copyright © 2011-2022 走看看