分配机器(基础dp)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_33598125/article/details/101295474

题目描述:
某总公司拥有高效生产设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为总公司提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。 分配原则:每个公司有权获得任意数目的设备,但总台数不得超过总设备数M。其中M<=100,N<=100。
输入:
第一行为两个整数M,N。接下来是一个N×M的矩阵,其中矩阵的第i行的第j列的数Aij表明第i个公司分配j台机器的盈利。所有数据之间用一个空格分隔。
输出:
只有一个数据,为总公司分配这M台设备所获得的最大盈利。

样例输入
3 2
1 2 3
2 3 4
样例输出
4

【分析】动态规划基础题型。

dp[i][j]表示前i+1个公司分配j+1台机器时的最大盈利。(因为i,j下标从0开始)

d p [ i ] [ j ] = m a x k ( d p [ i 1 ] [ j ] , d p [ i 1 ] [ j k ] + A [ i 1 ] [ k 1 ] ) dp[i][j]=max_k(dp[i-1][j],dp[i-1][j-k]+A[i-1][k-1]) ( :A的下标从0开始的,dp的下标计算从1开始的;前面的和数dp[i-1][j]其实是后面k=0时的情况,就是第i个公司不分配机器的意思,因为后面A不会遍历到这个情况,故在前面加上。)

def solution(A,m,n):
    dp=[[0 for k in range(m+1)]for i in range(n+1)]
    #dp_ij表示前i+1个公司分配j台机器的最大盈利
    for i in range(1,n+1):
        for j in range(1,m+1):
            dp[i][j]=max([dp[i-1][j]]+[dp[i-1][j-k]+A[i-1][k-1] for k in range(1,j+1)])
    return dp[-1][-1]

s=map(int,raw_input().split(" ")) #m,n
A=[]
for n in range(s[1]):
    A.append(map(int,raw_input().split(" "))) #A_ij 表示第i+1个公司分配j+1台机器的盈利
print(solution(A,s[0],s[1]))

#测试用例:
s=[15,10] #15台机器,10个公司
A=[[ 36, 107, 184, 283, 286, 292, 361, 393, 425, 469, 475, 496, 577,656, 713],
   [ 67,  68, 120, 136, 207, 279, 327, 413, 443, 521, 534, 542, 632,643, 719],
   [ 86, 136, 223, 273, 315, 317, 363, 369, 455, 554, 570, 591, 657,670, 685],
   [  8, 105, 179, 217, 306, 332, 373, 387, 407, 478, 520, 547, 645,670, 685],
   [ 82,  99, 198, 249, 291, 372, 453, 542, 561, 589, 603, 654, 700,730, 757],
   [ 88, 104, 134, 140, 224, 227, 277, 302, 358, 440, 530, 587, 635,715, 770],
   [  1,  61, 113, 117, 209, 223, 286, 289, 336, 364, 405, 431, 527,573, 642],
   [ 96, 176, 247, 312, 346, 375, 410, 419, 477, 572, 574, 587, 620,676, 744],
   [ 75, 127, 225, 296, 370, 370, 463, 473, 491, 537, 602, 664, 680,721, 728],
   [ 82, 133, 205, 205, 272, 295, 316, 393, 445, 512, 593, 637, 680,707, 745]]
#输出:1167
def solution(A,m,n):
    dp=[[0 for k in range(m+1)]for i in range(n+1)]
    #dp_ij表示前i+1个公司分配j台机器的最大盈利
    for i in range(1,n+1):
        for j in range(1,m+1):
            dp[i][j]=max([dp[i-1][j]]+[dp[i-1][j-k]+A[i-1][k-1] for k in range(1,j+1)])
    return dp[-1][-1]
print(solution(A,s[0],s[1]))

猜你喜欢

转载自blog.csdn.net/qq_33598125/article/details/101295474