zoukankan      html  css  js  c++  java
  • 百度之星平衡负载(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

    解答思路:最优划分用动态规划解决,我认为其中比较关键的是

    1)如何转化问题,即使用符号表示待解决的问题。

    本题中,设f(i,k)表示数组a[i…N]分成k部分的最优值。

    2)状态转移方程。

    本题为f(i,k)=min(j)max{f(j,k-1), sum(i, j-1)}, i < j <= N-k+2   ,k = 2,…,K.

    3)初始状态的确定。

    本题为f(i,1) = sum(i, N), i = 1,...,N.即k=1为初始状态。

    Ps:我觉得做动态规划的时候,最好还是找一个小规模问题,列一个表计算一下,就能把握i,j,k的范围和加深对题目解答的理解,切记切记!

    #include <stdio.h>
    #define MIN(a,b) (a)<(b)?(a):(b)
    #define MAX(a,b) (a)>(b)?(a):(b)
    
    int a[1001];
    int f[1001][1001];
    int tmpMax[1001];
    
    int sum(int i, int j)
    {
        int s = 0;
        for (int k = i; k <= j; k++)
        {
            s+= a[k];
        }
        return s;
    }
    
    int main()
    {
        int N, k;
        scanf("%d %d",&N,&k);
        do 
        {
            int i = 1;;
            while (i<=N)
            {
                scanf("%d", &a[i]);
                i++;
            }
            //f[i][k]表示a[i...N] 分成k 部分的最优划分方案
            for (int i = 1; i <= N; i ++)
            {
                f[i][1] = sum(i,N);
            }
            //DP
            int tmpmin;
            for (int nk = 2; nk <= k; ++nk)
            {
                for (int i = 1; i < N - nk + 2; i++)
                {
                    tmpmin = 0x7FFFFFFF;
                    for (int j = i+1; j <= N - nk + 2; j++)
                    {
                        //对每个j,比较f[j][nk-1] 和sum(i,j-1)两部分的最大值
                        tmpMax[j] = -1;
                        tmpMax[j] = MAX(f[j][nk-1], sum(i,j-1));
                        //对所有的j的最大值,取最小值即为f[i][nk]
                        tmpmin= MIN(tmpmin,tmpMax[j]);
                    }
                    f[i][nk] = tmpmin;            
                }
    
            }
            printf("%d\n",f[1][k]);
    
            scanf("%d %d",&N,&k);
        } while (N != 0 && k != 0);
    }
    不经历风雨,怎么见彩虹!
  • 相关阅读:
    springboot之session、cookie
    Springboot的异步线程池
    spring自带的定时任务功能@EnableScheduling
    SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递
    sss
    sss
    sss
    sss
    sss
    sss
  • 原文地址:https://www.cnblogs.com/ivorfeng/p/2985710.html
Copyright © 2011-2022 走看看