• 平衡负载(2013年百度之星3月23号竞赛题目一)


    平衡负载

      Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。

      例如N=5,K=2,每个任务需要时间分别为5,3,1,4,7分钟,那么我们可以分成(5)(3 1 4 7)两部分,这样第一台服务器所花时间就是5分钟,而第二台机器需要花15分钟,当然,所有任务完成的时间是按最迟完成的那台服务器的时间,即这样划分的话完成所有任务所需要的时间就是15分钟。而另外一种划分方法是(5 3 1)(4 7),这种划分方案完成所有任务的时间就是11分钟,也是最优的一种划分方案。

      现在你的任务就是根据给定的N,K和每个任务要花费的时间,找出使完成所有任务时间最短的方案。

      输入:

        多组输入。

        第一行输入N和K(1<=K<=N<=10000)。

        第二行输入N个不大于1000的正整数,表示各个任要花费的时间。

        N=K=0表示输入结束。

      输出:

        每行输出一个整数,对应对于每个数据(除了N=K=0不用输出)。

      样例输入:

        5 1
        5 3 1 4 7
        5 2
        5 3 1 4 7
        5 3
        5 3 1 4 7
        10 3
        1 2 3 4 5 6 7 8 9 10
        0 0

      样例输出:

        20
        11
        8
        21
     
    思路:
      初看这个题目,觉得可以用dfs来做,不过效率肯定是比较低的,所以后来想想,其实这道题目挺符合dp使用条件的,有这重复的子问题,有这最优子结构和无后效性,所以就打算用dp做了,首先定义状态dp[x][y],表示将前y个任务分到前x台服务器,完成前y个任务的最短时间。状态转移方程为:
      dp[x][y] = min{max{dp[x - 1][y1] , sy}} 其中y1取值为[x - 1, y - 1],sy = time[y1 + 1] + time[y2 + 1] + ...+time[y]
      如果直接定义dp[10000][10000],那空间太大了,通过状态转移方程可以知道,dp[x][y]只与dp[x - 1][y1]有关,所以可以定义dp[2][10000]来节省空间。代码如下:
     1 #include <stdio.h>
     2 
     3 #define max(a, b) a > b ? a : b
     4 int n, k;
     5 int time[10005];
     6 int dp[2][10005];
     7 int temp[10005];
     8 
     9 int main(void)
    10 {
    11     int i, j, min, l;
    12 
    13     while (scanf("%d%d", &n, &k), n && k)
    14     {
    15         for (i = 1; i <= n; i ++)
    16             scanf("%d", &time[i]);
    17         dp[1][1] = time[1];
    18         for (i = 2; i <= n; i ++)
    19             dp[1][i] = dp[1][i - 1] + time[i];
    20         for (j = 2;  j <= k; j ++)
    21         {
    22             for (i = j; i <= n; i ++)
    23             {
    24                 min = 100000000;
    25                 temp[0] = 0;
    26                 for (l = i - 1; l >= j - 1; l --)
    27                 {
    28                     temp[i - l] = temp[i - l - 1] + time[l + 1];
    29                     if (max(dp[(j + 1) % 2][l] , temp[i - l]) < min)
    30                         min = max(dp[(j + 1) % 2][l] , temp[i - l]);    
    31                 }
    32                 dp[j % 2][i] = min;
    33                 printf("%d ", dp[j % 2][i]);
    34             }
    35             printf("\n");
    36         }
    37         printf("%d\n", dp[k % 2][n]);
    38     }
    39     return 0;
    40 }
     
     
  • 相关阅读:
    九月三十学习报告
    九月二十九学习报告
    九月二十八学习报告
    九月二十七学习报告
    九月二十五学习报告
    九月二十四学习报告
    九月二十三学习报告
    九月二十二学习报告
    九月二十学习报告
    网络协议中HTTP,TCP,UDP,Socket,WebSocket的优缺点/区别
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/3022913.html
Copyright © 2020-2023  润新知